www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Is this a bug or feature?

reply Li Jie <cpunion gmail.com> writes:
Code:

























I expect it output "3", but the output is a big number, not "3".

If comment std.gc.fullCollect(), it output "3", and it is right.

I think a closure must save all contexts, isn't it?
Jan 15 2007
parent reply Kirk McDonald <kirklin.mcdonald gmail.com> writes:
Li Jie wrote:
 Code:
 























 
 I expect it output "3", but the output is a big number, not "3".
 
 If comment std.gc.fullCollect(), it output "3", and it is right.
 
 I think a closure must save all contexts, isn't it?
D does not have true closures. If the stack frame of the enclosing function is invalidated, then all bets are off. In Foo.foo above, the 'value' variable is a member of the 'this' reference. When Foo.foo returns, that delegate literal's context pointer is invalidated, and (therefore) so is the 'this' reference. If you want a delegate with a more persistent context, you must use a delegate to a member function, as in: class Foo { int value = 3; ~this() { writefln("dtor"); } void foo() { writefln(value); } } void main() { // Note the '&' void delegate() dg = &(new Foo).foo; std.gc.fullCollect(); dg(); } -- Kirk McDonald Pyd: Wrapping Python with D http://pyd.dsource.org
Jan 16 2007
next sibling parent reply BCS <ao pathlink.com> writes:
Reply to Kirk,

 Li Jie wrote:
 
[...]
 D does not have true closures. If the stack frame of the enclosing
 function is invalidated, then all bets are off.
 
 In Foo.foo above, the 'value' variable is a member of the 'this'
 reference. When Foo.foo returns, that delegate literal's context
 pointer is invalidated, and (therefore) so is the 'this' reference.
 
 If you want a delegate with a more persistent context, you must use a
 delegate to a member function, as in:
 
 class Foo {
 int value = 3;
 ~this() { writefln("dtor"); }
 void foo() {
 writefln(value);
 }
 }
 void main() {
 // Note the '&'
 void delegate() dg = &(new Foo).foo;
 std.gc.fullCollect();
 dg();
 }
What I would like to see is "scoped" delegate literals. This would let you make a delegate literal and say what pointer to use for the context. My choice for a syntax would be allowing delegates as dot operators on object references and other pointers. class Foo { int value = 3; int delegate() foo() { return this.{return value;}; } }
Jan 16 2007
parent reply Kirk McDonald <kirklin.mcdonald gmail.com> writes:
BCS wrote:
 Reply to Kirk,
 
 Li Jie wrote:
[...]
 D does not have true closures. If the stack frame of the enclosing
 function is invalidated, then all bets are off.

 In Foo.foo above, the 'value' variable is a member of the 'this'
 reference. When Foo.foo returns, that delegate literal's context
 pointer is invalidated, and (therefore) so is the 'this' reference.

 If you want a delegate with a more persistent context, you must use a
 delegate to a member function, as in:

 class Foo {
 int value = 3;
 ~this() { writefln("dtor"); }
 void foo() {
 writefln(value);
 }
 }
 void main() {
 // Note the '&'
 void delegate() dg = &(new Foo).foo;
 std.gc.fullCollect();
 dg();
 }
What I would like to see is "scoped" delegate literals. This would let you make a delegate literal and say what pointer to use for the context. My choice for a syntax would be allowing delegates as dot operators on object references and other pointers. class Foo { int value = 3; int delegate() foo() { return this.{return value;}; } }
Method literals, eh? Nifty. -- Kirk McDonald Pyd: Wrapping Python with D http://pyd.dsource.org
Jan 16 2007
parent BCS <ao pathlink.com> writes:
Reply to Kirk,

 BCS wrote:

 Method literals, eh? Nifty.
Not just methods: int[] foo; (&foo).{ int ret = 0; foreach(int i; *this) ret += i; return ret; } maybe even anything that can fit int a size_t (byte, short, int) Why not interface literals? interface I { int foo(); } struct S { int i; } auto a = new S; I i = s.I // I don't like the syntax, but... { int foo() { return this.i; } } Of course this requiters that interfaces be re implemented using context/v-table pairs, but that is an old soap-box.
Jan 16 2007
prev sibling parent reply %u <u fearof.spm> writes:
== Quote from Kirk McDonald (kirklin.mcdonald gmail.com)'s article
 If you want a delegate with a more persistent context
      void foo() {
Doesn't this solution only work because the newed and collected memory is not overwritten? Therefore "more persistent" only means until it is overwritten? Shouldn't one code
      static void foo() {
Jan 16 2007
parent BCS <ao pathlink.com> writes:
Reply to %u,

 == Quote from Kirk McDonald (kirklin.mcdonald gmail.com)'s article
 
 If you want a delegate with a more persistent context void foo() {
 
Doesn't this solution only work because the newed and collected memory is not overwritten? Therefore "more persistent" only means until it is overwritten? Shouldn't one code
 static void foo() {
 
A delegate is a context/function pointer pair. There for, as long as you keep the delegate around, the Foo won't get collected.
Jan 16 2007