When running calculations, you can generate the code including S-expressions nodes. This uses a mechanism for packing the code in the resource. After building the code, you can insert it into the main program using the EvaluateCode function. For debugging purposes, you can convert the code to a string using the FormatCode function.
Possible node types in S-expressions that can be used for code generation:
tuple
type in SQL.The S-expressions nodes form a directed graph. Atoms are always leaf nodes, because they cannot contain child nodes.
In the text representation, S-expressions have the following format:
'"foo"
. The apostrophe character (') denotes quoting of the next line that is usually enclosed in quotation marks.'("foo" "bar")
. The apostrophe character (') denotes that there will be no function call in parentheses.(foo "bar")
. The first item inside the brackets is the mandatory name of the function followed by the function arguments.(lambda '(x y) (+ x y))
. The lambda
keyword is followed by a list of argument names and then by the body of the lambda function.x
. Unlike an atom, a string without an apostrophe character (') references a name in the current scope. When declaring a lambda function, the names of arguments are added to the body's visibility scope, and, if needed, the name is hidden from the global scope.world
.Serializing the code as S-expressions. The code must not contain free arguments of functions, hence, to serialize the lambda function code, you must pass it completely, avoiding passing individual expressions that might contain lambda function arguments.
SELECT FormatCode(AtomCode("foo"));
-- (
-- (return '"foo")
-- )
Build a code node with the world
type.
SELECT FormatCode(WorldCode());
-- (
-- (return world)
-- )
Build a code node with the atom
type from a string passed to the argument.
SELECT FormatCode(AtomCode("foo"));
-- (
-- (return '"foo")
-- )
Build a code node with the list
type from a set of nodes or lists of code nodes passed to arguments. In this case, lists of arguments are built in as separately listed code nodes.
SELECT FormatCode(ListCode(
AtomCode("foo"),
AtomCode("bar")));
-- (
-- (return '('"foo" '"bar"))
-- );
SELECT FormatCode(ListCode(AsList(
AtomCode("foo"),
AtomCode("bar"))));
-- (
-- (return '('"foo" '"bar"))
-- )
Build a code node with the built-in function call
from a string with the function name and a set of nodes or lists of code nodes passed to arguments. In this case, lists of arguments are built in as separately listed code nodes.
SELECT FormatCode(FuncCode(
"Baz",
AtomCode("foo"),
AtomCode("bar")));
-- (
-- (return (Baz '"foo" '"bar"))
-- )
SELECT FormatCode(FuncCode(
"Baz",
AsList(
AtomCode("foo"),
AtomCode("bar"))));
-- (
-- (return (Baz '"foo" '"bar"))
-- )
You can build a code node with the lambda function declaration
type from:
argument
type will be passed as arguments to this lambda function.argument
type will be passed as an argument to this lambda function.SELECT FormatCode(LambdaCode(($x, $y) -> {
RETURN FuncCode("+", $x, $y);
}));
-- (
-- (return (lambda '($1 $2) (+ $1 $2)))
-- )
SELECT FormatCode(LambdaCode(2, ($args) -> {
RETURN FuncCode("*", Unwrap($args[0]), Unwrap($args[1]));
}));
-- (
-- (return (lambda '($1 $2) (* $1 $2)))
-- )
Substituting the code node passed in the argument, into the main program code.
SELECT EvaluateCode(FuncCode("Int32", AtomCode("1"))); -- 1
$lambda = EvaluateCode(LambdaCode(($x, $y) -> {
RETURN FuncCode("+", $x, $y);
}));
SELECT $lambda(1, 2); -- 3
Substituting the code node representing the result of evaluating an expression passed in the argument, into the main program.
$add3 = EvaluateCode(LambdaCode(($x) -> {
RETURN FuncCode("+", $x, ReprCode(1 + 2));
}));
SELECT $add3(1); -- 4
Substituting into the main program the code node that represents an expression or a lambda function passed in the argument. If free arguments of lambda functions were found during the substitution, they are calculated and substituted into the code as in the ReprCode function.
$lambda = ($x, $y) -> { RETURN $x + $y };
$makeClosure = ($y) -> {
RETURN EvaluateCode(LambdaCode(($x) -> {
RETURN FuncCode("Apply", QuoteCode($lambda), $x, ReprCode($y))
}))
};
$closure = $makeClosure(2);
SELECT $closure(1); -- 3