UNPKG

@holgerengels/compute-engine

Version:

Symbolic computing and numeric evaluations for JavaScript and Node.js

104 lines (103 loc) 4.03 kB
/* 0.26.0-alpha2 */ import type { BoxedExpression } from './public'; /*** * ### THEORY OF OPERATIONS * * A `["Function"]` expression has its own scope. * This scope includes the parameters and local variables. * * Some expressions with anonymous parameters (e.g. `["Add", "_", 1]`) * are rewritten to a `["Function"]` expression with anonymous parameters * (e.g. `["Function", ["Add", "_", 1], "_"]`). * * The **body** of a `["Function"]` expression may have its own scope * (for example if it's a `["Block"]` expression) or may not have a scope * at all (if it's a number, i.e. `["Function", 1]`). the function body may * be a number, a symbol or (more commonly) an function expression. * * * #### DURING BOXING (in makeLambda()) * * During the boxing/canonicalization phase of a function * (`["Function"]` expression or operator of expression): * * 1/ If not a `["Function"]` expression, the expression is rewritten * to a `["Function"]` expression with anonymous parameters * 2/ A new scope is created * 3/ The function parameters are declared in the scope * 4/ The function body is boxed in the context of the scope and the scope * is associated with the function * * * #### DURING EVALUATION (executing the result of makeLambda()) * * 1/ The arguments are evaluated in the current scope * 2/ The context is swapped to the function scope * 3/ The values of all the ids in this scope are reset * 4/ The parameters are set to the value of the arguments * 5/ The function body is evaluated in the context of the function scope * 6/ The context is swapped back to the current scope * 7/ The result of the function body is returned * */ /** * From an expression, return a predicate function, which can be used to filter. */ export declare function predicate(_expr: BoxedExpression): (...args: BoxedExpression[]) => boolean; /** * From an expression, create an ordering function, which can be used to sort. */ export declare function order(_expr: BoxedExpression): (a: BoxedExpression, b: BoxedExpression) => -1 | 0 | 1; /** * Given an expression, rewrite it to a canonical Function form. * * - explicit parameters (no change) * ["Function", ["Add, "x", 1], "x"] * -> ["Function", ["Add, "x", 1], "x"] * * - single anonymous parameters: * ["Add", "_", 1] * -> ["Function", ["Add", "_", 1], "_"] * * - multiple anonymous parameters: * ["Add", "_1", "_2"] * -> ["Function", ["Add", "_1", "_2"], "_1", "_2"] * * */ export declare function canonicalFunctionExpression(body: BoxedExpression, args?: BoxedExpression[]): [body: BoxedExpression, ...params: string[]]; /** * Apply arguments to an expression which is either * - a '["Function"]' expression * - an expression with anonymous parameters, e.g. ["Add", "_", 1] * - the identifier for a function, e.g. "Sin". */ export declare function apply(fn: BoxedExpression, args: ReadonlyArray<BoxedExpression>): BoxedExpression; /** * Return a lambda function, assuming a scoped environment has been * created and there is a single numeric argument */ export declare function makeLambdaN1(expr: BoxedExpression): ((arg: number) => number) | undefined; /** * Given an expression such as: * - ["Function", ["Add", 1, "x"], "x"] * - ["Function", ["Divide", "_", 2]] * - ["Multiply, "_", 3] * - ["Add, "_1", "_2"] * - "Sin" * * return a JS function that can be called with arguments. */ export declare function applicable(fn: BoxedExpression): (xs: ReadonlyArray<BoxedExpression>) => BoxedExpression | undefined; /** * Use applicableN when the function is known to be a function of a single * variable and the argument is a number. * * Unlike "apply", applicable returns a function that can be called * with an argument. * */ export declare function applicableN1(fn: BoxedExpression): (x: number) => number; /** * Give a string like "f(x,y)" return, ["f", ["x", "y"]] */ export declare function parseFunctionSignature(s: string): [id: string, args: string[] | undefined];