#bake_arguments
is a directive that takes an existing function and creates a new function with the existing function’s arguments partially evaluated as constants at compile-time. This has similar functionality to currying in functional programming languages, except any random function argument parameter can be evaluated rather than depending on the order the parameters come in. The #bake_arguments
directive, unlike currying values in functional programming languages, cannot be done at runtime, and is only limited to compile-time evaluation.
add :: (a,b) => a+b;
add10 :: #bake_arguments add(a=10); // create an add10 function that adds 10 to a given number
b := 20;
c := add10(b); // prints out 30
Arguments can be baked into functions by adding a $
in front of the identifier.
funct :: ($a: int) -> int {return a + 100;} // $a is baked into the function due to `$` in front of a
$$
will attempt to bake arguments into the parameter list if the parameter value is constant. If not, it will be a regular function without the baking. You can use static #if
's to determine which version of the function is being called.
funct :: ($$a: int) -> int {
#if is_constant(a) {
print("a is constant\n");
return a + 100;
} else {
print("a is not constant\n");
return a + 100;
}
}
#bake_arguments
can also be used on a parameterized struct to partially evaluate the constants at compile-time.
A :: struct (M: int, N: int) {
array: [M][N] int;
}
AA :: #bake_arguments A(M=10);
a: AA(N=2);
print("a=(%,%)\n", a.M, a.N); //prints out "a=(10,2)".