umka-lang
umka-lang copied to clipboard
Implement closures
Allow capturing variables from outer function's stack/heap frame:
fn adder(x: int): fn (y: int): int {
return fn (y: int): int {
return x + y
}
}
fn main() {
add5 := adder(5)
a := add5(7)
printf(repr(a) + '\n') // 12
}
This would require changing the internal representation of functions from
int64_t entry;
to
struct
{
int64_t entry;
void *upvalues;
}
The API functions umkaCall() and umkaGetFunc() will also have to be changed.
Beware of extremely perverse cases like the following one taken from Crafting Interpreters.
fun outer() {
var x = "value";
fun middle() {
fun inner() {
print x;
}
print "create inner closure";
return inner;
}
print "return from outer";
return middle;
}
var mid = outer();
var in = mid();
in();
The example from Crafting Interpreters rewritten in Umka:
fn outer(): fn(): fn() {
x := "value"
middle := fn(): fn() |x| {
inner := fn() |x| {
printf("%s\n", x)
}
printf("create inner closure\n")
return inner
}
printf("return from outer\n")
return middle
}
fn main() {
mid := outer()
inn := mid()
inn()
}
Output:
return from outer
create inner closure
value