Jump to page: 1 2
Thread overview
Closure capture loop variables
Apr 30, 2015
Freddy
Apr 30, 2015
Vladimir Panteleev
Apr 30, 2015
Freddy
Apr 30, 2015
Vladimir Panteleev
Apr 30, 2015
Marc Schütz
Apr 30, 2015
Vladimir Panteleev
Apr 30, 2015
Ali Çehreli
Apr 30, 2015
ketmar
May 01, 2015
Marc Schütz
May 01, 2015
Walter Bright
May 01, 2015
Adam D. Ruppe
May 01, 2015
Walter Bright
May 01, 2015
deadalnix
May 02, 2015
Adam D. Ruppe
May 02, 2015
deadalnix
May 02, 2015
ketmar
May 01, 2015
deadalnix
May 02, 2015
Idan Arye
May 03, 2015
Marc Schütz
April 30, 2015
I understand that
----
import std.stdio;
void main(){
	int delegate() func;
	foreach(i;0..10){
		if(i==5){
			func= () => i;
		}
	}
	writeln(func());//9
}
----
captures the loop variable,but why does
----
import std.stdio;

void main(){
	int delegate() func;
	foreach(i;0..10){
		auto copy=i;
		if(i==5){
			func= () => copy;
		}
	}
	writeln(func());//should be 5
}

----
still print 9.
April 30, 2015
On Thursday, 30 April 2015 at 01:16:20 UTC, Freddy wrote:
> I understand that
> ----
> import std.stdio;
> void main(){
> 	int delegate() func;
> 	foreach(i;0..10){
> 		if(i==5){
> 			func= () => i;
> 		}
> 	}
> 	writeln(func());//9
> }
> ----
> captures the loop variable,but why does
> ----
> import std.stdio;
>
> void main(){
> 	int delegate() func;
> 	foreach(i;0..10){
> 		auto copy=i;
> 		if(i==5){
> 			func= () => copy;
> 		}
> 	}
> 	writeln(func());//should be 5
> }
>
> ----
> still print 9.

Because "copy" is still modified every time "i" is.

You can either put "copy" inside the "if":

----
import std.stdio;

void main(){
	int delegate() func;
	foreach(i;0..10){
		if(i==5){
			auto copy=i;
			func= () => copy;
		}
	}
	writeln(func());//should be 5
}
----

Or you can create a closure for each iteration:

----
import std.stdio;

void main(){
	int delegate() func;
	foreach(i;0..10){
		(){
			auto copy=i;
			if(i==5){
				func= () => copy;
			}
		}();
	}
	writeln(func());//should be 5
}
----
April 30, 2015
On Thursday, 30 April 2015 at 01:19:45 UTC, Vladimir Panteleev wrote:
> Because "copy" is still modified every time "i" is.
But shouldn't copy be redeclared every loop iteration (or the compiler could pretend to redeclare it).
April 30, 2015
On Thursday, 30 April 2015 at 03:58:44 UTC, Freddy wrote:
> On Thursday, 30 April 2015 at 01:19:45 UTC, Vladimir Panteleev wrote:
>> Because "copy" is still modified every time "i" is.
> But shouldn't copy be redeclared every loop iteration (or the compiler could pretend to redeclare it).

No, it will have the same address every time.
April 30, 2015
On Thursday, 30 April 2015 at 05:23:55 UTC, Vladimir Panteleev wrote:
> On Thursday, 30 April 2015 at 03:58:44 UTC, Freddy wrote:
>> On Thursday, 30 April 2015 at 01:19:45 UTC, Vladimir Panteleev wrote:
>>> Because "copy" is still modified every time "i" is.
>> But shouldn't copy be redeclared every loop iteration (or the compiler could pretend to redeclare it).
>
> No, it will have the same address every time.

The current behaviour is wrong:
https://issues.dlang.org/show_bug.cgi?id=2043
https://issues.dlang.org/show_bug.cgi?id=8621
April 30, 2015
On Thursday, 30 April 2015 at 12:01:32 UTC, Marc Schütz wrote:
> On Thursday, 30 April 2015 at 05:23:55 UTC, Vladimir Panteleev wrote:
>> On Thursday, 30 April 2015 at 03:58:44 UTC, Freddy wrote:
>>> On Thursday, 30 April 2015 at 01:19:45 UTC, Vladimir Panteleev wrote:
>>>> Because "copy" is still modified every time "i" is.
>>> But shouldn't copy be redeclared every loop iteration (or the compiler could pretend to redeclare it).
>>
>> No, it will have the same address every time.
>
> The current behaviour is wrong:
> https://issues.dlang.org/show_bug.cgi?id=2043
> https://issues.dlang.org/show_bug.cgi?id=8621

These are slightly different problems. I think Freddy's programs are working as designed.

D closures should work in the same way as, e.g., JS closures. Try rewriting the program in JavaScript. If it behaves in the same way, it's not a D bug.
April 30, 2015
On 04/30/2015 05:55 AM, Vladimir Panteleev wrote:

> D closures should work in the same way as, e.g., JS closures. Try
> rewriting the program in JavaScript. If it behaves in the same way, it's
> not a D bug.

Right.

I remember Seth Ladd's Dart language presentation at the local ACCU in Silicon Valley. He was explaining how Dart was different from other languages in this respect. I think he had mentioned JavaScript with the behavior that he was not fond of, so he had designed the language the way OP wants.

He explains it here:


http://blog.sethladd.com/2012/01/for-loops-in-dart-or-fresh-bindings-for.html

Ali

April 30, 2015
On Thu, 30 Apr 2015 12:55:16 +0000, Vladimir Panteleev wrote:

> D closures should work in the same way as, e.g., JS closures.
js closures are fubared.

May 01, 2015
On Thursday, 30 April 2015 at 12:55:18 UTC, Vladimir Panteleev wrote:
> On Thursday, 30 April 2015 at 12:01:32 UTC, Marc Schütz wrote:
>> On Thursday, 30 April 2015 at 05:23:55 UTC, Vladimir Panteleev wrote:
>>> On Thursday, 30 April 2015 at 03:58:44 UTC, Freddy wrote:
>>>> On Thursday, 30 April 2015 at 01:19:45 UTC, Vladimir Panteleev wrote:
>>>>> Because "copy" is still modified every time "i" is.
>>>> But shouldn't copy be redeclared every loop iteration (or the compiler could pretend to redeclare it).
>>>
>>> No, it will have the same address every time.
>>
>> The current behaviour is wrong:
>> https://issues.dlang.org/show_bug.cgi?id=2043
>> https://issues.dlang.org/show_bug.cgi?id=8621
>
> These are slightly different problems. I think Freddy's programs are working as designed.
>
> D closures should work in the same way as, e.g., JS closures. Try rewriting the program in JavaScript. If it behaves in the same way, it's not a D bug.

I don't think so. JS is not comparable, because it's scoping rules are different from D. Closures should capture the variable, not its memory location. And both `i` and `copy` are distinct variables in each loop iteration, they just happen to share the same location, because they have non-intersecting lifetimes.
May 01, 2015
On 4/30/2015 5:55 AM, Vladimir Panteleev wrote:
> I think Freddy's programs are working as designed.

Yes, they are.

D closures capture variables by reference. No, we're not changing that.
« First   ‹ Prev
1 2