Implement closures
itssamuelrowe opened this issue · 0 comments
itssamuelrowe commented
Zen can encourage functional programming with closures. Given Zen does not treat functions as expressions, mostly due to the limitations imposed by indentation based blocks, local functions can be used to simulate closures.
Consider the following example which makes use of a closure.
// Test.zen
define makeCounter()
var count = 1
define next()
count = count + 1
return count
return next
define main(...arguments)
var next = makeCounter()
var value = next()
print(value)
In the background, the compiler treats the above example as if it were of the following form.
// Test.zen
class Test$Closure1 extends Closure
var counter
define new(counter0)
counter = counter0
define invoke()
counter = counter + 1
return counter
define makeCounter()
var counter = 1
var next = new Test$Closure1(counter)
return next
define main(...arguments)
var next = makeCounter()
var value = next.invoke()
print(value)
- Are closures really necessary in Zen?
- When a local variable or local field is treated as a function, the compiler
translates it toreference.invoke(...)
. Initially, the target method can be invoked viainvoke_dynamic
. Once inheritance is implemented, such invocations can be done via theinvoke_virtual
instruction. - How is
object.field()
handled? The bootstrap method is a good place to load the
target method.
bootstrap(...) {
...
zen_Object_t* self = ...;
zen_Function_t* function = ...;
...
if (function == NULL) {
zen_Field_t* field = ...;
if (field != NULL) {
zen_Class_t* class0 = zen_Object_getClass(field);
function = zen_Class_getFunction(class0, "invoke", ...);
...
}
}
return function;
}