Documentation
¶
Overview ¶
Package functions is 012's function library: the FuncDef table, the evaluation of formulas (operators and calls), the argument, range and criteria helpers functions share, decimal arithmetic, and the questions JEV functions ask.
It knows nothing of sheets or storage. A formula reads cells through a Reader over a Book, which the engine (internal/sheet) implements, and the engine finds functions through the table (LookupFunc) when it parses formulas. Dependencies point one way: formula and value below, the engine above.
Index ¶
- Variables
- func EvalParts(n Node, paths [][]int, get *Reader, at Addr) (Part, []Part)
- func IsPending(v Value) bool
- func IsVolatile(n Node) bool
- func StreamingFuncs() []string
- func Streams(name string) bool
- type Addr
- type Agg
- type Array
- type Book
- type Format
- type FuncDef
- type Node
- type Part
- type Reader
- type Rect
- type RemoteAnswer
- type RemoteCall
- type RemoteSource
- type StreamAnswer
- type StreamArg
- type StreamCall
- type Value
Constants ¶
This section is empty.
Variables ¶
var ( // Pending is shown while an answer is on its way. Pending = Value{Kind: value.Error, Str: "Loading…"} // ErrNoRemote means JEV functions can't run: there is no API key. ErrNoRemote = Value{Kind: value.Error, Str: "#N/A"} )
var ErrRemote = Value{Kind: value.Error, Str: "#ERROR!"}
ErrRemote is a question the model couldn't answer, e.g. a network failure; the context line says why.
Functions ¶
func EvalParts ¶ added in v0.3.0
EvalParts evaluates n in the cell at, as EvalCell does, and returns what it computed, with the array it spills, and what each part at paths computed. A path is child indexes from the root, in formula.EachChild's order; the empty path is the whole formula. A path to a reference, name or literal records nothing: those are read where they stand.
func IsVolatile ¶
IsVolatile reports whether n calls a function whose result changes without its inputs changing (TODAY, NOW, RAND).
func StreamingFuncs ¶ added in v0.6.0
func StreamingFuncs() []string
StreamingFuncs lists the functions that read a source of any size, in alphabetical order, for the docs and messages.
Types ¶
type Addr ¶
Addr identifies a cell by zero-based column and row.
func Intersect ¶
Intersect is the cell of r a formula in the cell at reads where it wants one value: a single cell is itself; a single column gives the cell in at's row, a single row the cell in at's column, when that lies within r (implicit intersection, on whatever sheet r is on). Any other range has no such cell, which is #VALUE!.
type Agg ¶
type Agg struct {
// contains filtered or unexported fields
}
Agg is the running aggregate of SUM-like functions (SUM, AVERAGE, COUNT, COUNTA, MIN, MAX, PRODUCT): what they read of a range, added in order. The engine keeps one per range shared by a recalculation (Book.RangeAgg).
type Array ¶ added in v0.2.0
Array is the value of a formula that computes several: Rows by Cols entries. Only the top-left DRows by DCols hold values of their own, in V row by row; every other entry is Fill. A whole column read as an array costs what it holds: A:A is 1,048,576 rows, of which the rows holding data are stored, the rest blank.
type Book ¶
type Book interface {
// Cell is the current value of a cell, evaluated first if it's
// dirty; #REF! on a sheet that doesn't exist.
Cell(sheet string, a Addr) Value
// Scan reads the cells of r that hold something, row by row, from
// the cell from on (those before it in that order are skipped): their
// addresses into addrs and, unless vals is nil, their values into
// vals, evaluating them as Cell does. It stops when addrs is full or
// just after a value that is an error, so no cell past the first
// error is evaluated, and returns how many it read: -1 when the sheet
// doesn't exist.
Scan(sheet string, r Rect, from Addr, addrs []Addr, vals []Value) int
// Bounds is the smallest range holding every stored cell of r, with
// false if r holds none; exists is false when the sheet doesn't.
Bounds(sheet string, r Rect) (b Rect, any, exists bool)
// RangeAgg is the aggregate of r that SUM-like functions share within
// a recalculation (see Agg), with the first error in it, or false
// when r should be read directly.
RangeAgg(sheet string, r Rect) (Agg, *Value, bool)
// Fold adds the cells of r that hold something to s, row by row, as
// SUM-like functions read a range (Agg.Add), evaluating them as Cell
// does and stopping at the first error, which it returns. On a sheet
// that doesn't exist the range is one #REF!.
Fold(sheet string, r Rect, s Agg) (Agg, *Value)
// Ask looks up the answer to a remote question (JEV functions). The
// value is an error when there is none to give: Pending while it is
// on its way, ErrNoRemote when nothing answers them.
Ask(call RemoteCall) (RemoteAnswer, Value)
// Paged reports whether the sheet is a paged source (stream.go),
// whose ranges a function is given through Stream.
Paged(sheet string) bool
// Stream answers a call over paged sources, with an array when it
// computes several values: Pending while the answer is on its way.
Stream(call StreamCall) (Value, *Array)
}
Book is how formulas reach the workbook: the engine implements it, once for each sheet whose formulas it evaluates. Sheets are named as references write them; "" is the formula's own sheet.
Every method takes and returns plain values, never a callback: a function value or pointer passed through an interface escapes to the heap, so a callback per range read would cost an allocation that an engine reading its own cells doesn't pay. Ranges are read instead in chunks, into buffers the Reader keeps and reuses (Scan), and each function walks them with callbacks of its own that stay on the stack.
type Format ¶
Format is a cell's number format.
func InferFormat ¶
InferFormat picks the format Sheets shows a formula's result in when the cell is Automatic: dates from date functions, and otherwise the format of the first formatted input, so =B2+B3 of currency shows currency and a date plus days shows a date.
type FuncDef ¶
type FuncDef struct {
Name string
Args string // signature shown to users, e.g. "value1, [value2, ...]"
Desc string
Min int
Max int // -1 for variadic
// Volatile functions (TODAY, NOW, RAND) change without their inputs
// changing, so every recalculation recomputes them.
Volatile bool
// contains filtered or unexported fields
}
FuncDef describes a spreadsheet function. The table drives parsing (arity checks), evaluation, autocomplete and help.
func LookupFunc ¶
LookupFunc finds a function by name or alias, case-insensitively (callers pass upper case).
func Of ¶
Of is the function a parsed call calls: always one of the table's, as long as the parser found functions through LookupFunc.
func (*FuncDef) Question ¶
func (f *FuncDef) Question(args []Node, get *Reader) (RemoteCall, error)
Question is the remote question a call of f asks with its current arguments, or an error when they don't make one.
type Node ¶
Node is a parsed formula expression.
func Const ¶ added in v0.6.0
Const is a node that evaluates to v: what the engine binds a name to while what it names can't be read yet (a source being opened shows Loading…).
func Decimalize ¶
Decimalize returns a copy of n that evaluates in decimal: operators are marked, and functions with a decimal twin call it.
type Part ¶ added in v0.3.0
type Part struct {
Value Value
// Array holds the first rows and columns of an array the part
// computed, with Rows and Cols its whole size; nil otherwise.
Array *Array
// Lambda is set when the part computed a LAMBDA.
Lambda bool
// Reached is false for a part the formula never computed.
Reached bool
}
Part is what one part of a formula computed the first time it was computed.
type Reader ¶
type Reader struct {
// contains filtered or unexported fields
}
Reader is what a function is given to read the cells its arguments refer to: a Book, and the buffers ranges are read through. It is a concrete type so the callbacks functions pass to it stay on the stack.
func NewReader ¶
NewReader reads cells through book. depth counts how deeply evaluation nests (cells, operators and calls), for the engine to put off cells past its limit. With dense, functions read every address of their ranges, as they did before ranges were clipped to what they hold, so tests can check that the two agree.
func (*Reader) Forget ¶ added in v0.2.0
func (rd *Reader) Forget()
Forget drops the ranges read as arrays. The engine calls it as each recalculation starts and ends: within one, a range's values don't change once read, since reading it evaluates its dirty cells first (a range holding a cell being evaluated is a cycle, an error either way), and spilled cells are written between passes.
type RemoteAnswer ¶
type RemoteAnswer struct {
Noul float64 // probability of yes
Choice string
Score float64
Confidence float64 // in Choice or Score, not a probability of truth
Failed string
}
RemoteAnswer is the model's answer. Which fields are set depends on the call's Kind; Failed explains an answer that couldn't be had.
type RemoteCall ¶
type RemoteCall struct {
Kind string `json:"kind"` // "noul", "choice" or "score"
State any `json:"state"`
Instructions string `json:"instructions"`
// Criteria depends on Kind: noul is [2]string{yes, no} (either may be
// empty), choice is map[label]description, score is []string levels.
Criteria any `json:"criteria"`
}
RemoteCall is one question for the model, built from a function's arguments. It isn't comparable: Key identifies it by its content.
func (RemoteCall) Key ¶
func (c RemoteCall) Key() string
Key identifies a question by its content: the answer cache and the engine's list of cells waiting for answers are keyed by it. JEV cells are volatile, so every recalculation looks each one up: with thousands of them, encoding the key with encoding/json took most of the time an answer spent in recalc. The shapes a RemoteCall holds are encoded by hand, each value tagged and each string length-prefixed so different calls never share a key; anything else falls back to JSON.
type RemoteSource ¶
type RemoteSource interface {
Lookup(RemoteCall) (RemoteAnswer, bool)
}
RemoteSource answers RemoteCalls. Lookup returns false while an answer isn't known, and queues the call.
type StreamAnswer ¶ added in v0.6.0
StreamAnswer is what a StreamCall computes: a value, or an array of them, and for an error that needs one, why.
func EvalStream ¶ added in v0.6.0
func EvalStream(c StreamCall, book Book, budget int) StreamAnswer
EvalStream computes c over book, a Book that reads the paged sheets its ranges name by streaming them: in the background, where reading takes as long as the source is big. A function not in streaming is given the source's ranges only up to budget cells.
type StreamArg ¶ added in v0.6.0
StreamArg is an argument of a StreamCall: a range of a paged sheet (Sheet set, as the engine names the source), or a value.
type StreamCall ¶ added in v0.6.0
type StreamCall struct {
Fn string
// Dec is set when the call is computed in decimal (decimal.go).
Dec bool
Args []StreamArg
}
StreamCall is a call of a function some of whose arguments are ranges of paged sheets. It isn't comparable: Key identifies it by content.
func (StreamCall) Key ¶ added in v0.6.0
func (c StreamCall) Key() string
Key identifies the call by its content.
type Value ¶
Value is the computed contents of a cell.
func Eval ¶
Eval computes a formula where one value is wanted, reading the cells it refers to through get. A range where one value is wanted reads as the cell in the row or column last given to EvalAt (see intersect), and an array as its first entry.
func EvalAt ¶
EvalAt computes the formula in the cell at as one value, so that a range used where one value is wanted reads as the cell in at's row or column (implicit intersection, as Sheets and Excel do). Evaluations nest, one cell's formula reading another's through the same Reader, so the cell before is given back afterwards.
func EvalCell ¶ added in v0.2.0
EvalCell computes the formula in the cell at, as EvalAt, keeping the array it computes when that is several values for Spilled: the cell shows the first, and the engine spills the array from it. A 1x1 array is one value. A range that is the whole formula is an array, as Sheets spills =B2:B9.