D isn't the only language with janky closure semantics

Timon Gehr timon.gehr at gmx.ch
Sat Aug 30 13:13:08 UTC 2025


On 8/30/25 01:17, H. S. Teoh wrote:
> On Fri, Aug 29, 2025 at 10:51:10PM +0000, Steven Schveighoffer via Digitalmars-d wrote:
>> On Friday, 29 August 2025 at 22:28:17 UTC, H. S. Teoh wrote:
>>> Now, JS is certainly not a model language to follow, but it's
>>> interesting how it shares with D the same issue over closures
>>> involving loop variables.
>>>
>>> I guess that means we're not alone. :-P  Even though this situation
>>> is definitely not ideal.
>>
>> Oh yeah, JS has similar behavior. You get the desired behavior by
>> using `let` at the variable declaration. Otherwise, it becomes a
>> regular declaration (one instance per function).
>>
>> I think your original code will work as you want with:
>>
>> ```js
>> for (let button of buttons) {
>> ```
> 
> Oooh yes, that *is* exactly what I was looking for.  I already got
> bitten before by for(... of) without `let`... still haven't learned my
> lesson, it seems.
> 
> 
>> Would be nice to have a similar trick for D...
> 
> Sneaky syntax proposal:
> 
> ```d
> 	void delegate()[] dgs;
> 	foreach (scope i; 0 .. 100) {	// N.B. `scope`
> 		dgs ~= () {
> 			writefln("%d", i); // <-- closes over independent instance of `i`
> 		};
> 	}
> ```
> 
> ;-)
> 
> 
> T
> 

The variable `i` is already a variable local to the loop body. The fact 
that it is shared between loop iterations is a form of memory 
corruption, it is not really comparable to the JS case.

JS just did not use to even have variables that are local to a scope, 
which they more or less fixed with `let`/`const`. D does not have this 
problem, we do have local variables, closures are just not implemented 
correctly.

I think the problem really isn't that there is no dedicated syntax to 
make it not corrupt memory, it's that it does not just work, even if you 
do declare a local intermediate variable in the loop body. x)


More information about the Digitalmars-d mailing list