Thread overview
Closures over temporary variables
Jun 14, 2022
Anonymouse
Jun 14, 2022
bauss
Jun 14, 2022
Ali Çehreli
June 14, 2022

What is the correct way of making this output 0 1 2?

void delegate()[] dgs;

foreach (immutable i; 0..3)
{
    dgs ~= () => writeln(i);
}

foreach (dg; dgs)
{
    dg();  // outputs: `2 2 2`
}
June 14, 2022

On Tuesday, 14 June 2022 at 08:26:53 UTC, Anonymouse wrote:

>

What is the correct way of making this output 0 1 2?

void delegate()[] dgs;

foreach (immutable i; 0..3)
{
    dgs ~= () => writeln(i);
}

foreach (dg; dgs)
{
    dg();  // outputs: `2 2 2`
}

You have to do it like this:

dgs ~= ( (n) => () { writeln(n); })(i);

Because D hasn't fixed their million dollar mistake after so many years:

https://issues.dlang.org/show_bug.cgi?id=2043

https://issues.dlang.org/show_bug.cgi?id=23136

June 14, 2022
On 6/14/22 02:04, bauss wrote:

> You have to do it like this:
>
> ```
> dgs ~= ( (n) => () { writeln(n); })(i);
> ```

The same thing with a named function as well as with iota():

import std.range;
import std.algorithm;
import std.stdio;

void main() {
  void delegate()[] dgs;

  auto makeDg(int i) {
    return () => writeln(i);
  }

  foreach (immutable i; 0 .. 3)
  {
    dgs ~= makeDg(i);
  }

  iota(3).each!(i => dgs ~= () => writeln(i));

  foreach (dg; dgs)
  {
    dg();
  }
}

Ali