Closures and loop scope
Idan Arye
GenericNPC at gmail.com
Tue Jun 4 12:55:38 PDT 2013
On Tuesday, 4 June 2013 at 19:42:39 UTC, Adam D. Ruppe wrote:
> On Tuesday, 4 June 2013 at 19:19:57 UTC, Idan Arye wrote:
>> Can this be fixed? *Should* this be fixed?
>
> For what it's worth, Javascript works the same way. So I've
> come to the pattern of having a function return a function when
> it is looping in both languages.
>
> So while it might not be ideal, it isn't totally unexpected
> since other languages do it too.
Ruby is the most interesting:
arr=[]
for i in 0...5
arr<< lambda{i}
end
puts arr.map{|e|e.call}.to_s
prints [4, 4, 4, 4, 4], because it uses the built-in for loop, so
`i` is reused in all iterations. On the other hand:
arr=[]
(0...5).each do|i|
arr<< lambda{i}
end
puts arr.map{|e|e.call}.to_s
prints [0, 1, 2, 3, 4], because each call to the rubyblock has
it's own stack frame and it's own `i`. This can also be done in D:
auto arr=new ulong delegate()[5];
auto iotaDelegate(T...)(T args){
return (int delegate(ref ulong) dlg){
foreach(i;iota(args)){
dlg(i);
}
return 0;
};
}
foreach(i;iotaDelegate(arr.length)){
arr[i]=()=>i;
}
writeln(arr.map!`a()`());
This prints [0, 1, 2, 3, 4], because each iteration of the
foreach is actually an function call, so it has it's own stack
frame.
More information about the Digitalmars-d
mailing list