Can we fix this?
Steven Schveighoffer
schveiguy at gmail.com
Wed Sep 29 16:47:23 UTC 2021
On 9/29/21 10:16 AM, jfondren wrote:
> On Wednesday, 29 September 2021 at 10:44:53 UTC, Imperatorn wrote:
>> https://issues.dlang.org/show_bug.cgi?id=2043
>>
>> Impossible?
>
> ... Documentation:
>
> D has two kinds of blocks, the `{ ... }` kind and the `(){ ... }();`
> kind. Within the former, for efficiency, [something about this bug].
> Within the latter, closure environments will be as expected from other
> languages at the cost of additional allocation. These "bubble blocks"
> are admittedly ugly but this is part of D's firm stand against the
> programming practices of the Scheme community.
>
> ```d
> void delegate()[] dgList;
>
> void main() {
> import std.stdio : writeln;
>
> foreach(int i; [1, 2, 3]) {
> auto b = i+2;
> dgList ~= { writeln(b); };
> writeln(&b); // b will be the *same* on each iteration
> }
> foreach (dg; dgList)
> dg(); // output: 5 5 5
> }
> ```
>
> vs.
>
> ```d
> void delegate()[] dgList;
>
> void main() {
> import std.stdio : writeln;
>
> foreach(int i; [1, 2, 3]) (){
> auto b = i+2;
> dgList ~= { writeln(b); };
> writeln(&b); // b will be *unique* on each iteration
> }();
> foreach (dg; dgList)
> dg(); // output: 3 4 5
> }
> ```
This is not what I would have ever thought of, and it's kind of prone to
error, since `i` is still used from within the lambda. It would not be
hard to mess it up:
```d
foreach(int i; [1, 2, 3]) (){
dgList ~= { writeln(i + 2); }; // still outputs 5 5 5
}();
```
What we need is a syntax to specify which values are captured and which
variables are referenced.
What I normally do if I need something like this is:
```d
foreach(int i; [1, 2, 3]) {
dgList ~= (b) { return {writeln(b);};} (i + 2);
// or less error prone:
dgList ~= (i) { return {writeln(i + 2);};} (i);
}
```
Which specifies the captured variable. But it's a lot of punctuation.
Some imagined syntax?
```d
dgList ~= (@capture i) {writeln(i + 2);};
// or:
dgList ~= (@capture i) => writeln(i + 2);
```
-Steve
More information about the Digitalmars-d
mailing list