Zig NEWS

Discussion on: Closure Pattern in Zig

Collapse
 
neurocyte profile image
Neurocyte • Edited

These are not closures.

Your closure environment consists entirely of comptime known constant values and not variables. That makes them plain old functions, not closures. This is a function generator pattern, not a closure pattern.

The usual definition of a closure (that you started your article with) is a function with bound free variables which implies some sort of additional state. Usually implemented as an additional environment pointer (often hidden by language syntax) which may vary at runtime.

Collapse
 
houghtonap profile image
Andrew Houghton

The definition for ClosureBind is wrong, since it used comptime this: ClosureScope. The correct definition for ClosureBind should have omitted comptime, thus allowing free bound variables at runtme. I'll update the article. Thanks for the feedback.

Collapse
 
neurocyte profile image
Neurocyte

Removing comptime from ClosureScope doesn't change anything. ClosureFunc returns a type and is therefore a comptime function and anything you pass to it has to be comptime known and is therefore implicitly also comptime. ClosureFunc is a comptime function generator that binds the function to some static values. It does not generate closures.

You can verify this in your example by passing a variable to TextInRange instead of a literal. Will get the message error: unable to resolve comptime value.

You can't implement closures without an additional state parameter at the closure call site. This is why closures in static languages are always some sort of object.

Thread Thread
 
houghtonap profile image
Andrew Houghton

In response to your comment I added the following test which confirms your assertion that the presented implementation works only with compile time static values and my misunderstanding of Zig's comptime concept.

test "[Comptime Only Issue]" {

    // Test reuse invocation of the closure.
    var from: u32 = undefined;
    var to: u32 = undefined;

    from = 2;
    to = 5;

    const closure = TextInRange(from, to);

    const text = closure("0123456789");
    print("text = {s}\n", .{text});
}
Enter fullscreen mode Exit fullscreen mode

After further review of the presented implementation and a few minor changes to ClosureType and ClosureBind the above test passes using runtime variables. I'll update the article. Thanks for clarifying Zig's comptime concept.