digitalmars.D - A delegate problem, create delegation in loop
- lijie (15/39) Jul 04 2012 }
- bearophile (11/23) Jul 05 2012 import std.stdio;
- lijie (4/30) Jul 05 2012 Thanks bearophile.
- Denis Shelomovskij (40/60) Jul 05 2012 This program behaves as expected. Just like C# program that will give
- lijie (14/33) Jul 05 2012 How to distinguish which variables will be copied to the closure context...
- Timon Gehr (38/70) Jul 06 2012 It is simple. Variable declarations introduce a new variable. Closures
- lijie (2/38) Jul 06 2012 Understood, thanks.
Hi, My test code:import std.stdio; void main() { void delegate()[] functions; foreach (i; 0 .. 5) { functions ~= { printf("%d\n", i); };}foreach (func; functions) { func(); } }output: $ dmd DMD64 D Compiler v2.059 ... $ ./main5 5 5 5 5Seems like all delegations shared a stack variable, I think delegation must copy the value into its context. I can avoid it: void delegate() createDelegate(int i) {void exec() { printf("%d\n", i); } return &exec; } foreach (i; 0 .. 5) { functions ~= createDelegate(i); }But hope for improve it. Best regards, -- Li Jie
Jul 04 2012
lijie:import std.stdio; void main() { void delegate()[] functions; foreach (i; 0 .. 5) functions ~= ((int j) => { printf("%d\n", j); })(i); foreach (func; functions) func(); } Bye, bearophileimport std.stdio; void main() { void delegate()[] functions; foreach (i; 0 .. 5) { functions ~= { printf("%d\n", i); };}foreach (func; functions) { func(); } }
Jul 05 2012
On Thu, Jul 5, 2012 at 3:36 PM, bearophile <bearophileHUGS lycos.com> wrote:lijie: import std.stdio;Thanks bearophile. Best regards, -- Li Jieimport std.stdio; void main() { void delegate()[] functions; foreach (i; 0 .. 5) functions ~= ((int j) => { printf("%d\n", j); })(i); foreach (func; functions) func(); }void main() { void delegate()[] functions; foreach (i; 0 .. 5) { functions ~= { printf("%d\n", i); };}foreach (func; functions) { func(); } }
Jul 05 2012
05.07.2012 9:54, lijie пишет:
Hi,
My test code:
import std.stdio;
void main() {
void delegate()[] functions;
foreach (i; 0 .. 5) {
functions ~= {
printf("%d\n", i);
};
}
foreach (func; functions) {
func();
}
}
output:
5
5
5
5
5
the same output:
---
delegate void MyFunc();
class Program
{
static void Main()
{
var funcs = new MyFunc[5];
for (int i = 0; i < funcs.Length; ++i)
funcs[i] = new MyFunc(() => System.Console.WriteLine(i));
foreach (var f in funcs)
f();
}
}
---
because "i" is the same for every iteration. Different situation is for
---
for (int i = 0; i < funcs.Length; ++i)
{
int t = i;
funcs[i] = new MyFunc(() => System.Console.WriteLine(t));
}
---
This D loop
---
foreach(i; 0 .. 5) {
int t = i;
functions ~= { printf("%d\n", t); };
}
---
prints "4" five times. It's Issue 2043:
http://d.puremagic.com/issues/show_bug.cgi?id=2043
I'm not posting workaround here because bearophile already did it.
--
Денис В. Шеломовский
Denis V. Shelomovskij
Jul 05 2012
On Thu, Jul 5, 2012 at 4:26 PM, Denis Shelomovskij <
verylonglogin.reg gmail.com> wrote:
---
for (int i = 0; i < funcs.Length; ++i)
{
int t = i;
funcs[i] = new MyFunc(() => System.Console.WriteLine(t));
}
---
This D loop
---
foreach(i; 0 .. 5) {
int t = i;
functions ~= { printf("%d\n", t); };
}
---
prints "4" five times. It's Issue 2043:
http://d.puremagic.com/issues/**show_bug.cgi?id=2043
<http://d.puremagic.com/issues/show_bug.cgi?id=2043>
How to distinguish which variables will be copied to the closure context?
I think this is a scope rule, in the previous code, there are three
variables:
1. function arguments
2. loop variables
3. local variables
copied. There
are other rules? And why is the loop variable not local?
Thanks.
Best regards,
-- Li Jie
Jul 05 2012
On 07/06/2012 05:14 AM, lijie wrote:On Thu, Jul 5, 2012 at 4:26 PM, Denis Shelomovskij <verylonglogin.reg gmail.com <mailto:verylonglogin.reg gmail.com>> wrote: --- for (int i = 0; i < funcs.Length; ++i) { int t = i; funcs[i] = new MyFunc(() => System.Console.WriteLine(t)); } --- doesn't. This D loop --- foreach(i; 0 .. 5) { int t = i; functions ~= { printf("%d\n", t); }; } --- prints "4" five times. It's Issue 2043: http://d.puremagic.com/issues/__show_bug.cgi?id=2043 <http://d.puremagic.com/issues/show_bug.cgi?id=2043> How to distinguish which variables will be copied to the closure context?They are not copied, they are stored there.I think this is a scope rule, in the previous code, there are three variables: 1. function arguments 2. loop variables 3. local variables copied. There are other rules? And why is the loop variable not local? Thanks. Best regards, -- Li JieIt is simple. Variable declarations introduce a new variable. Closures that reference the same variable will see the same values. ---- foreach(i; 0..3) { functions~={writeln(i);}; } is the same as for(int i=0;i<3;i++) { functions~={writeln(i);}; } is the same as {int i=0;for(;i<3;i++) { functions~={writeln(i);}; }} is the same as { int i=0; { functions~={writeln(i);}; } i++; { functions~={writeln(i);}; } i++; { functions~={writeln(i);}; } i++; } ---- foreach(i; 0..3){ int j=i; functions~={writeln(j);}; } is the same as for(int i=0;i<3;i++){ int j=i; functions~={writeln(j);}; } is the same as {int i=0;for(i<3;i++){ int j=i; functions~={writeln(j);}; } is the same as { int i=0; { int j=i; functions~={writeln(j);}; } i++; { int j=i; functions~={writeln(j);}; } i++; { int j=i; functions~={writeln(j);}; } i++; } ---- I think it is quite intuitive.
Jul 06 2012
On Fri, Jul 6, 2012 at 3:06 PM, Timon Gehr <timon.gehr gmx.ch> wrote:
It is simple. Variable declarations introduce a new variable. Closures
that reference the same variable will see the same values.
----
foreach(i; 0..3) { functions~={writeln(i);}; }
is the same as
for(int i=0;i<3;i++) { functions~={writeln(i);}; }
is the same as
{int i=0;for(;i<3;i++) { functions~={writeln(i);}; }}
is the same as
{
int i=0;
{ functions~={writeln(i);}; }
i++;
{ functions~={writeln(i);}; }
i++;
{ functions~={writeln(i);}; }
i++;
}
----
foreach(i; 0..3){ int j=i; functions~={writeln(j);}; }
is the same as
for(int i=0;i<3;i++){ int j=i; functions~={writeln(j);}; }
is the same as
{int i=0;for(i<3;i++){ int j=i; functions~={writeln(j);}; }
is the same as
{
int i=0;
{ int j=i; functions~={writeln(j);}; }
i++;
{ int j=i; functions~={writeln(j);}; }
i++;
{ int j=i; functions~={writeln(j);}; }
i++;
}
----
I think it is quite intuitive.
Understood, thanks.
Jul 06 2012









lijie <cpunion gmail.com> 