@holgerengels/compute-engine
Version:
Symbolic computing and numeric evaluations for JavaScript and Node.js
104 lines (103 loc) • 4.03 kB
TypeScript
/* 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];