Baking and Currying Values

#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)".