Function - FunctionBuilder
Function.FunctionBuilderA FunctionBuilder to build a data transformation in Elara.
Methods on the FunctionBuilder enable you to directly transform data from any number of input
return Streams. The body of the function works similarly to most imperative
languages (like JavaScript/TypeScript) allowing for definition of temporary variables (with let), reassignment
of defined variables (with assign), branching (with if, ifNull and match), loops (with while, forArray, forSet, forDict),
as well as logging and raising errors (with log, warn and error). Inside any of these statements you can use
East Expressions to access and manipulate data in scope.
A corresponding
Template can be created using.toTemplate().
Example
// Create a function to add two integer streams, equivalent to the Javascript function
//
// function f(a, b) {
// let c = a + b;
// return { c };
// }
//
// f(1n, 2n) == 3n
const a = new SourceBuilder("a").value({ value: 1n })
const b = new SourceBuilder("b").value({ value: 2n })
const f = new FunctionBuilder("f")
.input("a", a.outputStream())
.input("b", b.outputStream())
.body(block => block
.let("c", vars => Add(vars.a, vars.b))
.return({ c: vars => vars.c })
)
Type parameters
| Name | Type |
|---|---|
FunctionName | extends string |
Inputs | extends Record = |
RecursiveInputs | extends Record = |
Functions | extends Record<string, Record> = |
MLs | extends Record = |
Procs | extends Record = |
Returns | extends null | Record = null |
Hierarchy
-
Builder↳
FunctionBuilder
Function
constructor
• new FunctionBuilder(name, module, inputs, recursiveInputs, defaults, functions, mls, procs, statements, outputs):
FunctionBuilder
Create a FunctionBuilder to build a data tansformation in Elara.
Methods on the FunctionBuilder enable you to directly transform data from any number of input
return Streams. The body of the function works similarly to most imperative
languages (like JavaScript/TypeScript) allowing for definition of temporary variables (with let), reassignment
of defined variables (with assign), branching (with if, ifNull and match), loops (with while, forArray, forSet, forDict),
as well as logging and raising errors (with log, warn and error). Inside any of these statements you can use
East Expressions to access and manipulate data in scope.
A corresponding
Template can be created using.toTemplate().
Type parameters
| Name | Type |
|---|---|
FunctionName | extends string |
Inputs | extends Record = |
RecursiveInputs | extends Record = |
Functions | extends Record<string, Record> = |
MLs | extends Record = |
Procs | extends Record = |
Returns | extends null | Record = null |
Parameters
| Name | Type |
|---|---|
name | FunctionName |
module | ModulePath |
inputs | Record |
recursiveInputs | Record |
defaults | Record |
functions | Functions |
mls | MLs |
procs | Procs |
statements | null | FunctionStatement[] |
outputs | null | Record |
Returns
FunctionBuilder
Example
// Create a function to add two integer streams, equivalent to the Javascript function
//
// function f(a, b) {
// let c = a + b;
// return { c };
// }
//
// f(1n, 2n) == 3n
const a = new SourceBuilder("a").value({ value: 1n })
const b = new SourceBuilder("b").value({ value: 2n })
const f = new FunctionBuilder("f")
.input("a", a.outputStream())
.input("b", b.outputStream())
.body(block => block
.let("c", vars => Add(vars.a, vars.b))
.return({ c: vars => vars.c })
)
Overrides
Builder.constructor
body
▸ body(body):
FunctionBuilder<FunctionName, Inputs, RecursiveInputs, Functions, MLs, Procs, GetReturns<ReturnType>>
Define the "body" of this function, where computations are performed on inputs and outputs are returned.
The body can be thought of as a block of code containing statements like let and return,
or even nested blocks of code (using if or while). This code is executed much like the body of a function
in imperative languages, like JavaScript/TypeScript.
To use this method, an empty "block" of code is injected on which you can use define statements using the builder pattern (or fluent code pattern) and return the result.
Type parameters
| Name | Type |
|---|---|
B | extends (block: BlockBuilder<{ [K in string | number | symbol]: Variable } & { [K in string | number | symbol]: Variable }, { [K in string | number | symbol]: { [I in string | number | symbol]: Functions[K][I]["type"] } }, MLs, Procs, null>) => TerminalBlockBuilder<null | Record> |
Parameters
| Name | Type |
|---|---|
body | B |
Returns
FunctionBuilder<FunctionName, Inputs, RecursiveInputs, Functions, MLs, Procs, GetReturns<ReturnType>>
Example
// Create a function to add two integer streams, equivalent to the Javascript function
//
// function f(a, b) {
// let c = a + b;
// return { c };
// }
//
// f(1n, 2n) == 3n
const a = new SourceBuilder("a").value({ value: 1n })
const b = new SourceBuilder("b").value({ value: 2n })
const f = new FunctionBuilder("f")
.input("a", a.outputStream())
.input("b", b.outputStream())
.body(block => block
.let("c", vars => Add(vars.a, vars.b))
.return({ c: vars => vars.c })
)
input
▸ input(name, stream):
FunctionBuilder<FunctionName, Inputs & { [K in string]: T }, RecursiveInputs, Functions, MLs, Procs, Returns>
Define an input streams as an input parameter of function. Each input stream is given a
variable name that is accessible in the body of the function.
Type parameters
| Name | Type |
|---|---|
Name | extends string |
T | extends EastType |
Parameters
| Name | Type |
|---|---|
name | Name |
stream | Stream |
Returns
FunctionBuilder<FunctionName, Inputs & { [K in string]: T }, RecursiveInputs, Functions, MLs, Procs, Returns>
Example
// Create a function to add two integer streams, equivalent to the Javascript function
//
// function f(a, b) {
// let c = a + b;
// return { c };
// }
//
// f(1n, 2n) == 3n
const a = new SourceBuilder("a").value({ value: 1n })
const b = new SourceBuilder("b").value({ value: 2n })
const f = new FunctionBuilder("f")
.input("a", a.outputStream())
.input("b", b.outputStream())
.body(block => block
.let("c", vars => Add(vars.a, vars.b))
.return({ c: vars => vars.c })
)
ml
▸ ml(ml):
FunctionBuilder<FunctionName, Inputs, RecursiveInputs, Functions, MLs & { [K in string]: MLDescription<StructType, T> }, Procs, Returns>
Include a machine-learning function that can evaluated inside the expressions of this FunctionBuilder.
Type parameters
| Name | Type |
|---|---|
MLName | extends string |
Features | extends Record |
T | extends EastType |
Parameters
| Name | Type | Description |
|---|---|---|
ml | AbstractMLBuilder | the MLModelBuilder model add to the FunctionBuilder |
Returns
FunctionBuilder<FunctionName, Inputs, RecursiveInputs, Functions, MLs & { [K in string]: MLDescription<StructType, T> }, Procs, Returns>
Example
// create an ml function
const my_ml_function = new MLModelBuilder("my_ml_function")
.feature("feature1", FloatType)
.feature("feature2", StringType)
.output(FloatType)
// create the predict_amount function
const feature1 = new SourceBuilder("feature1").value({ value: 3.14 })
const feature2 = new SourceBuilder("feature2").value({ value: "abc" })
const f = new FunctionBuilder("f")
.input("feature1", feature1.outputStream())
.input("feature2", feature2.outputStream())
.ml(my_ml_function)
.body(block => block
.let("output", (vars, mls) => mls.my_ml_function(Struct({ feature1: vars.feature1, feature2: vars.feature2 })))
.return({ output: vars => vars.output })
)
outputStreams
▸ outputStreams(): Returns extends Record ? { [K in string | number | symbol]: Stream } :
Return the output streams for this function.
Returns
Returns extends Record ? { [K in string | number | symbol]: Stream } :
Example
// Create a function to add two integer streams, equivalent to the Javascript function
//
// function f(a, b) {
// let c = a + b;
// return { c };
// }
//
// f(1n, 2n) == 3n
const a = new SourceBuilder("a").value({ value: 1n })
const b = new SourceBuilder("b").value({ value: 2n })
const f = new FunctionBuilder("f")
.input("a", a.outputStream())
.input("b", b.outputStream())
.body(block => block
.let("c", vars => Add(vars.a, vars.b))
.return({ c: vars => vars.c })
)
const c_stream = f.outputStreams().c
procedure
▸ procedure(procedure):
FunctionBuilder<FunctionName, Inputs, RecursiveInputs, Functions, MLs, Procs & { [K in string]: ProcedureDescription<ProcName, StructType, T> }, Returns>
Include a procedure that can evaluated inside the expressions of this FunctionBuilder.
Type parameters
| Name | Type |
|---|---|
ProcName | extends string |
ProcInputs | extends Record |
T | extends EastType |
Parameters
| Name | Type | Description |
|---|---|---|
procedure | ProcedureFinalizer | the Procedure to add to the FunctionBuilder |
Returns
FunctionBuilder<FunctionName, Inputs, RecursiveInputs, Functions, MLs, Procs & { [K in string]: ProcedureDescription<ProcName, StructType, T> }, Returns>
Example
// create a procedure to multiply two numbers
const my_procedure = new Procedure("my_procedure")
.input("x", FloatType)
.input("y", FloatType)
.output(FloatType)
.body(b => b
.return(vars => Multiply(vars.x, vars.y))
);
// create the predict_amount function
const x = new SourceBuilder("x").value({ value: 3.14 });
const y = new SourceBuilder("y").value({ value: 42.0 });
const f = new FunctionBuilder("f")
.input("x", x.outputStream())
.input("y", y.outputStream())
.procedure(my_procedure)
.body(block => block
.let("output", (vars, procs) => procs.my_procedure(Struct({ x: vars.x, y: vars.y })))
.return({ output: vars => vars.output })
);
toTemplate
▸ toTemplate(): Object
Return the template elements for this function.
Returns
Object
| Name | Type |
|---|---|
streams | Record |
tasks |
Example
// Create a function to add two integer streams, equivalent to the Javascript function
//
// function f(a, b) {
// let c = a + b;
// return { c };
// }
//
// f(1n, 2n) == 3n
const a = new SourceBuilder("a").value({ value: 1n })
const b = new SourceBuilder("b").value({ value: 2n })
const f = new FunctionBuilder("f")
.input("a", a.outputStream())
.input("b", b.outputStream())
.body(block => block
.let("c", vars => Add(vars.a, vars.b))
.return({ c: vars => vars.c })
)
export default f.toTemplate()
Overrides
Builder.toTemplate
Other
function
▸ function(f):
FunctionBuilder<FunctionName, Inputs, RecursiveInputs, Functions & { [K in string]: { [I in string | number | symbol]: Stream } }, MLs, Procs, Returns>
Elara functions can be defined recursively using optional input and output streams. This method declares another function that can be called as a result of this function, where "calling" the function implies providing the optional input values defined by recursiveInput.
Note that this interface is experimental and not recommended for usage at this time. It is up to the user to ensure termination and avoid infinite recursion and excessive usage of the Elara cluster.
Type parameters
| Name | Type |
|---|---|
Name | extends string |
R | extends Record |
F | extends FunctionBuilder<Name, Record, R, , , , null> |
Parameters
| Name | Type |
|---|---|
f | F |
Returns
FunctionBuilder<FunctionName, Inputs, RecursiveInputs, Functions & { [K in string]: { [I in string | number | symbol]: Stream } }, MLs, Procs, Returns>
recursiveInput
▸ recursiveInput(name, initial_value):
FunctionBuilder<FunctionName, Inputs, RecursiveInputs & { [K in string]: ReturnType["type"] }, Functions & { [K in string]: { [I in string | number | symbol]: Stream } & { [K in string]: Stream<ReturnType["type"]> } }, MLs, Procs, Returns>
Elara functions can be defined recursively using optional input and output streams. This method defines an "optional" inputs that have an initial default value, and can be provided recurssively by this or downstream functions.
Note that this interface is experimental and not recommended for usage at this time. It is up to the user to ensure termination and avoid infinite recursion and excessive usage of the Elara cluster.
Type parameters
| Name | Type |
|---|---|
Name | extends string |
F | extends (p: { [K in string | number | symbol]: Variable }) => EastFunction |
Parameters
| Name | Type |
|---|---|
name | Name |
initial_value | F |
Returns
FunctionBuilder<FunctionName, Inputs, RecursiveInputs & { [K in string]: ReturnType["type"] }, Functions & { [K in string]: { [I in string | number | symbol]: Stream } & { [K in string]: Stream<ReturnType["type"]> } }, MLs, Procs, Returns>
recursiveInputStreams
▸ recursiveInputStreams(): { [K in string | number | symbol]: Stream }
Elara functions can be defined recursively using optional input and output streams. This method returns the input streams defined via recursiveInput, which are written to when a function terminates with the recurse method.
Note that this interface is experimental and not recommended for usage at this time. It is up to the user to ensure termination and avoid infinite recursion and excessive usage of the Elara cluster.
Returns
{ [K in string | number | symbol]: Stream }