compute

package module
v0.0.0-...-117609a Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 13, 2025 License: BSD-3-Clause Imports: 5 Imported by: 0

README

compute: a generic streaming calculator.

GoDoc Go Report Card

Package compute implements a generic streaming calculator. The core type of the package is Pad - a map from type K cmp.Ordered to either type V any or a function of type func(...V) V. Pad provides methods for inserting keys and values/functions, and an iterator method that takes a sequence of keys and produces a sequence of K, V pairs where each V is either an existing value under the key K, or a result of calling the function under that key. During the iteration it is guaranteed that each function is called at most once (aka lazy evaluation).

Example:

func add(a, b int) int {
    return a + b
}

func mul(a, b int) int {
    return a * b
}

func Example() {
    // create a Pad
    pad := compute.NewPad[string, int]()

    // add values
    pad.SetVal("a", 1) // a = 1
    pad.SetVal("b", 2) // b = 2
    pad.SetVal("c", 3) // c = 3

    // add functions
    pad.SetFunc2("x", add, "a", "b") // x = a + b
    pad.SetFunc2("y", add, "b", "c") // y = b + c
    pad.SetFunc2("z", mul, "x", "y") // z = x * y

    // calculate
    for k, v := range pad.Calc("x", "y", "z") {
        fmt.Printf("%s = %d\n", k, v)
    }

    // Output:
    // x = 3
    // y = 5
    // z = 15
}

Possible applications:

  • With string keys and values of some numeric type it becomes an expression evaluator with symbol table (as in the example above);
  • With integer keys it can be used as an engine for spreadsheet-like calculations;
  • With string values and appropriate functions one can even develop a make-like utility on top of it.

For API details see documentation.

Details

The key sequence for calculations does not have to be in any particular order, Pad handles all the dependencies internally.

During the calculation existing values and functions in the Pad must not be modified, but new values and functions can be added. Provided that the sequence of keys being iterated over also includes those new values, a highly dynamic calculations can be performed.

The calculation itself does not modify the contents of the Pad, making it immutable and panic-safe, but this also means that all intermediate results (i.e., the calculated values) get discarded when the iteration ends.

The calculator stops with an error upon detecting a missing key or a cycle in the calculation graph.

Insertion of a new value/function is a rather cheap operation, and one Pad can potentially contain millions of values.

Documentation

Overview

Package compute implements a generic streaming calculator. The core type of the package is Pad - a map from type "K cmp.Ordered" to either type "V any" or a function of type "func(...V) V". Pad provides methods for inserting keys and values/functions, and an iterator method that takes a sequence of keys and produces a sequence of (K, V) pairs where each V is either an existing value under the key K, or a result of calling the function under that key. During the iteration it is guaranteed that each function is called at most once (aka lazy evaluation).

Example
package main

import (
	"fmt"

	"github.com/maxim2266/compute"
)

func add(a, b int) int {
	return a + b
}

func mul(a, b int) int {
	return a * b
}

func main() {
	// create a Pad
	pad := compute.NewPad[string, int]()

	// add values
	pad.SetVal("a", 1) // a = 1
	pad.SetVal("b", 2) // b = 2
	pad.SetVal("c", 3) // c = 3

	// add functions
	pad.SetFunc2("x", add, "a", "b") // x = a + b
	pad.SetFunc2("y", add, "b", "c") // y = b + c
	pad.SetFunc2("z", mul, "x", "y") // z = x * y

	// calculate
	for k, v := range pad.Calc("x", "y", "z") {
		fmt.Printf("%s = %d\n", k, v)
	}

}
Output:

x = 3
y = 5
z = 15

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Pad

type Pad[K cmp.Ordered, V any] struct {
	Err error // computation error, if any
	// contains filtered or unexported fields
}

Pad is a container for keys and values/functions.

func NewPad

func NewPad[K cmp.Ordered, V any]() *Pad[K, V]

NewPad constructs a new Pad.

func NewPadFrom

func NewPadFrom[K cmp.Ordered, V any](other *Pad[K, V]) *Pad[K, V]

NewPadSize constructs a new Pad as a copy of the given other Pad.

func NewPadSize

func NewPadSize[K cmp.Ordered, V any](size int) *Pad[K, V]

NewPadSize constructs a new Pad able to store at least the given number of keys.

func (*Pad[K, V]) Calc

func (p *Pad[K, V]) Calc(keys ...K) iter.Seq2[K, V]

Calc returns an iterator over the given list of keys. The iterator yields keys/value pairs where each value is either the value associated with the key, or a result of calling the function under that key.

func (*Pad[K, V]) CalcSeq

func (p *Pad[K, V]) CalcSeq(keys iter.Seq[K]) iter.Seq2[K, V]

Calc returns an iterator over the given sequence of keys. The iterator yields keys/value pairs where each value is either the value associated with the key, or a result of calling the function under that key.

func (*Pad[K, V]) Clear

func (p *Pad[K, V]) Clear()

Clear removes all keys from the Pad.

func (*Pad[K, V]) Delete

func (p *Pad[K, V]) Delete(key K)

Delete removes the given key, if it exists.

func (*Pad[K, V]) SetFunc

func (p *Pad[K, V]) SetFunc(key K, fn func(...V) V, args ...K)

SetFunc inserts the given generic function into the Pad.

func (*Pad[K, V]) SetFunc0

func (p *Pad[K, V]) SetFunc0(key K, fn func() V)

SetFunc0 inserts the given 0-argument function into the Pad.

func (*Pad[K, V]) SetFunc1

func (p *Pad[K, V]) SetFunc1(key K, fn func(V) V, arg0 K)

SetFunc1 inserts the given 1-argument function into the Pad.

func (*Pad[K, V]) SetFunc10

func (p *Pad[K, V]) SetFunc10(key K, fn func(V, V, V, V, V, V, V, V, V, V) V, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9 K)

SetFunc10 inserts the given 10-argument function into the Pad.

func (*Pad[K, V]) SetFunc2

func (p *Pad[K, V]) SetFunc2(key K, fn func(V, V) V, arg0, arg1 K)

SetFunc2 inserts the given 2-argument function into the Pad.

func (*Pad[K, V]) SetFunc3

func (p *Pad[K, V]) SetFunc3(key K, fn func(V, V, V) V, arg0, arg1, arg2 K)

SetFunc3 inserts the given 3-argument function into the Pad.

func (*Pad[K, V]) SetFunc4

func (p *Pad[K, V]) SetFunc4(key K, fn func(V, V, V, V) V, arg0, arg1, arg2, arg3 K)

SetFunc4 inserts the given 4-argument function into the Pad.

func (*Pad[K, V]) SetFunc5

func (p *Pad[K, V]) SetFunc5(key K, fn func(V, V, V, V, V) V, arg0, arg1, arg2, arg3, arg4 K)

SetFunc5 inserts the given 5-argument function into the Pad.

func (*Pad[K, V]) SetFunc6

func (p *Pad[K, V]) SetFunc6(key K, fn func(V, V, V, V, V, V) V, arg0, arg1, arg2, arg3, arg4, arg5 K)

SetFunc6 inserts the given 6-argument function into the Pad.

func (*Pad[K, V]) SetFunc7

func (p *Pad[K, V]) SetFunc7(key K, fn func(V, V, V, V, V, V, V) V, arg0, arg1, arg2, arg3, arg4, arg5, arg6 K)

SetFunc7 inserts the given 7-argument function into the Pad.

func (*Pad[K, V]) SetFunc8

func (p *Pad[K, V]) SetFunc8(key K, fn func(V, V, V, V, V, V, V, V) V, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7 K)

SetFunc8 inserts the given 8-argument function into the Pad.

func (*Pad[K, V]) SetFunc9

func (p *Pad[K, V]) SetFunc9(key K, fn func(V, V, V, V, V, V, V, V, V) V, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8 K)

SetFunc9 inserts the given 9-argument function into the Pad.

func (*Pad[K, V]) SetVal

func (p *Pad[K, V]) SetVal(key K, val V)

SetVal inserts the value at the given key.

func (*Pad[K, V]) Size

func (p *Pad[K, V]) Size() int

Size returns the number of keys currently in the Pad.

func (*Pad[K, V]) UpdateFrom

func (p *Pad[K, V]) UpdateFrom(other *Pad[K, V]) *Pad[K, V]

UpdateFrom updates the Pad with keys and values from the given other Pad.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL