digitalmars.D.learn - Is this a bug or feature?
- Li Jie <cpunion gmail.com> Jan 15 2007
- Kirk McDonald <kirklin.mcdonald gmail.com> Jan 16 2007
- BCS <ao pathlink.com> Jan 16 2007
- Kirk McDonald <kirklin.mcdonald gmail.com> Jan 16 2007
- BCS <ao pathlink.com> Jan 16 2007
- %u <u fearof.spm> Jan 16 2007
- BCS <ao pathlink.com> Jan 16 2007
Code:
# import std.gc;
#
# class Foo{
# private:
# int value = 3;
#
# public:
# ~this(){
# writefln("call destructor");
# }
#
# void delegate() foo(){
# return delegate void(){
# writefln(value);
# };
# }
# }
#
# void main(){
# void delegate() dg = (new Foo).foo;
# std.gc.fullCollect();
# dg();
# }
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
Li Jie wrote:Code: # import std.gc; # # class Foo{ # private: # int value = 3; # # public: # ~this(){ # writefln("call destructor"); # } # # void delegate() foo(){ # return delegate void(){ # writefln(value); # }; # } # } # # void main(){ # void delegate() dg = (new Foo).foo; # std.gc.fullCollect(); # dg(); # } 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
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
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
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
== Quote from Kirk McDonald (kirklin.mcdonald gmail.com)'s articleIf 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 codestatic void foo() {
Jan 16 2007
Reply to %u,== Quote from Kirk McDonald (kirklin.mcdonald gmail.com)'s articleIf you want a delegate with a more persistent context void foo() {
is not overwritten? Therefore "more persistent" only means until it is overwritten? Shouldn't one codestatic 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









BCS <ao pathlink.com> 