On Sunday, 21 January 2024 at 20:13:38 UTC, An Pham wrote:
On Saturday, 20 January 2024 at 15:59:59 UTC, Anonymouse wrote:
I remember reading this was an issue and now I ran into it myself.

```d
import std.stdio;

void main()
{
    auto names = [ "foo", "bar", "baz" ];
    void delegate()[] dgs;

    foreach (name; names)
    {
        dgs ~= () => writeln(name);
    }

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

Expected output: `foo`, `bar`, `baz`
Actual output:   `baz`, `baz`, `baz`

If I make `names` an `AliasSeq` it works, but I need it to be a runtime array.

Is there a workaround?

It is broken by design and the upper afraid to fix it because of broken backward compatible. This symptom was same as early C# and MS acknowledge it and fixed it
Happy coding

Very weird scoping.

The functional programmer's nightmare:
```d
import std.stdio;

    void main()
    {
        auto names = [ "foo", "bar", "baz" ];
        void delegate(int)[] dgs;

        string myname="Original ";

        foreach (name; names)
        {
           int j=0;
           void delegate(int) lambdaFunction =
            (int i)
            {
                writeln("N:",name," ",myname, j++," ",i); // ok
            };
           j=100;

           dgs ~= lambdaFunction;
        }


        int i=0;
        foreach (dg; dgs)
        {
            dg(i++);
            myname="Side effect ";
        }
    }

    ```
    ```
    ./a.out
    N:baz Original 100 0
    N:baz Side effect 101 1
    N:baz Side effect 102 2

```

Good: the function is indeed invoked.
Why the output starts with 100 and not 0?
Where "lives" variable j which is declared in the scope of the foreach-block?

Reply via email to