int factor = 2;
assert([2, 3].map!(a => a * factor).array == [4, 6]);
Then the `!` indicates that you're actually passing the lambda as a compiletime parameter to `map`. But the lambda can access the surrounding context! How does it pass a runtime value at compile time?So what you're passing is actually purely a function symbol. The way that it gets the stack reference to the surrounding function is that it's actually a nested function. And the way that `map` gets the stack reference to pass to the lambda is that, effectively, that instance of `map` is also a nested function of the calling function.
That's also why you cannot pass a lambda as a template parameter to a class method in D: it already has a context parameter, ie. the class reference.
In Neat, the value of the lambda is the stackframe reference, and it's just passed as a regular parameter:
int factor = 2;
assert([2, 3].map(a => a * factor).array == [4, 6]);
Which avoids this whole issue at the cost of requiring some cleverness with refcounting.It also encourages people not to think about what the structure of their templates, so you can end up with truly massive amounts of duplication.