On Wednesday, 30 March 2022 at 12:46:07 UTC, Vijay Nayar wrote:
Consider the following code example:

```d
import std.stdio;

void main()
{
  alias DelegateT = string delegate();

  // An array of delegates, each has their own scope.
  DelegateT[] funcs;
  foreach (i; ["ham", "cheese"]) {
    // Deliberately create a copy to keep in delegate scope.
    string myStr = i.dup;
// The delegate will hopefully carry this copy around in its own scope.
    funcs ~= (() => myStr ~ " sandwich");
  }
        
  foreach (f; funcs) {
    writeln(f());
  }
}
```

The expected output is: "ham sandwich" and then "cheese sandwich".

The actual output is: "cheese sandwich" and then "cheese sandwich".

It seems that the variable `myStr` is in a sort of shared scope for both functions in the array, and the last value written to it dominates.

How do I create a delegate that acts like a [closure](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Closures), that is, it carries with it the environment in which it was created?

You can also use `static foreach` and `alias`, although that will restrict that code to compile time usage only :/

```d
import std;
import std.stdio;

void main()
{
  alias DelegateT = string delegate();

  // An array of delegates, each has their own scope.
  DelegateT[] funcs;
  static foreach (alias i; ["ham", "cheese"]) {
    // Deliberately create a copy to keep in delegate scope.
    //string myStr = i.dup;
// The delegate will hopefully carry this copy around in its own scope.
    funcs ~= (() => /*myStr*/ i ~ " sandwich");
  }
        
  foreach (f; funcs) {
    writeln(f());
  }
}
```

Reply via email to