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 5the 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