August 29 Re: D isn't the only language with janky closure semantics | ||||
---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer | 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 -- Give a man a fish, and he eats once. Teach a man to fish, and he will sit forever. |
August 30 Re: D isn't the only language with janky closure semantics | ||||
---|---|---|---|---|
| ||||
Posted in reply to H. S. Teoh | 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)
|
Copyright © 1999-2021 by the D Language Foundation