Can we fix this?

jfondren julian.fondren at gmail.com
Thu Sep 30 02:50:13 UTC 2021


On Thursday, 30 September 2021 at 02:25:53 UTC, jfondren wrote:
> In basically every language that exists the expected behavior 
> from this code is 3 4 5.

Exceptions: Python, Nim, Rust, probably C++, probably Zig.

In order:

```python
funcs = []

for i in range(0, 3):
     n = i + 2
     funcs.append(lambda: print(n))

for f in funcs:
     f()  # output: 4 4 4
```

```nim
var funcs: seq[proc(): void]

for i in 0..2:
   let n = i + 2
   funcs.add (proc = echo n)

for f in funcs:
   f()  # output: 4 4 4
```

```rust
fn main() {
     let mut funcs = Vec::new();
     for i in 0 .. 3 {
         let n = i + 2;
         funcs.push(|| println!("{}", n));
//                 --                ^ borrowed value does not 
live long enough
//                 |
//                 value captured here
     }
//  - `n` dropped here while still borrowed
     for f in funcs {
         f();
     }
}
```

So, more like, "basically every GC language that exists", except 
for Python which has famously garbage lambdas. At the least, you 
can't say that this behavior is a barrier to popularity with 
Python getting lambdas so wrong.

The workaround in Rust's case is to add a `move` before the `||` 
there.

Nim documents this exact complaint in 
https://nim-lang.org/docs/manual.html#closures-creating-closures-in-loops , which points to stdlib workarounds.


More information about the Digitalmars-d mailing list