digitalmars.D - "heap" syntax
- Russ Lewis (28/28) Aug 30 2006 I mentioned this idea in the "future of lambda delegates" thread, but
- Johan Granberg (33/69) Aug 30 2006 Is a special syntax really desired for this sort of things. In other
- Russ Lewis (25/28) Aug 30 2006 I hear you, but disagree. The problems with automatic detection have
- Johan Granberg (20/30) Aug 31 2006 Ok thats bad it rules out possible optimization and it become a question...
I mentioned this idea in the "future of lambda delegates" thread, but don't know if anybody noticed. I'm starting a new thread for discussion. The problem at hand was how to declare that a stack frame should reside on the heap instead of on the stack. Somebody mentioned that we could put *some* of the variables on the heap, which lead me to this idea: int delegate() foo() { int x,y,z; // these varaibles are on the stack heap { // all variables declared inside this block are on the heap! int a = x+y+z; return delegate int() { return a++; } // this is ok to return, since its 'this' pointer points to // the heap, not the stack. } } Implementation-wise, my thought is that the language automatically allocates a region on the stack large enough for any variables in the heap{} block. The stack frame then has a pointer to that value. Deletate literals * When a delegate literal *only* references variables inside a heap{} block, then its 'this' pointer should point to the heap, of course. * When a delegate literal accesses variables on the stack, then its 'this' pointer should point to the stack. Q: Should it be legal to have a delegate which accesses both heap and stack variables? Probably, but won't it sometimes make it non-obvious which thing the delegate points to? BTW: There is no reason that heap{} blocks couldn't be nested. There might be cases where the outer heap area might become garbage while the inner heap area does not.
Aug 30 2006
Russ Lewis wrote:I mentioned this idea in the "future of lambda delegates" thread, but don't know if anybody noticed. I'm starting a new thread for discussion. The problem at hand was how to declare that a stack frame should reside on the heap instead of on the stack. Somebody mentioned that we could put *some* of the variables on the heap, which lead me to this idea: int delegate() foo() { int x,y,z; // these varaibles are on the stack heap { // all variables declared inside this block are on the heap! int a = x+y+z; return delegate int() { return a++; } // this is ok to return, since its 'this' pointer points to // the heap, not the stack. } } Implementation-wise, my thought is that the language automatically allocates a region on the stack large enough for any variables in the heap{} block. The stack frame then has a pointer to that value. Deletate literals * When a delegate literal *only* references variables inside a heap{} block, then its 'this' pointer should point to the heap, of course. * When a delegate literal accesses variables on the stack, then its 'this' pointer should point to the stack. Q: Should it be legal to have a delegate which accesses both heap and stack variables? Probably, but won't it sometimes make it non-obvious which thing the delegate points to? BTW: There is no reason that heap{} blocks couldn't be nested. There might be cases where the outer heap area might become garbage while the inner heap area does not.Is a special syntax really desired for this sort of things. In other languages there is something called static closures and if i understand them right they are often implemented so that the returned function gets a copy of its referred variables probably heap allocated. The downside with this is that to modify a referred variable a pointer is required but on the other hand it removes a chore from the programmer and a source of mistakes. (if we wanted to we could declare a syntax to override the copy part and instead pass a pointer. example follows) int c=0; void delegate() foo() { void a() { c++;//c is a copy and is unchanged after the return } return &a; } void bar() { int* f=&c; void b() { ++ c;//c is implicitly accessed trough a pointer ++*f;//this line is equivalent //f is a copy of a pointer but it points to the original //c in the case of c this is done by the compiler } return &b; } I don't know what's the better syntax but i feel that any syntax that require the variables to bee declared with special storage is prone to mistakes and bugs.
Aug 30 2006
Johan Granberg wrote:I don't know what's the better syntax but i feel that any syntax that require the variables to bee declared with special storage is prone to mistakes and bugs.I hear you, but disagree. The problems with automatic detection have already been discussed a lot in this newsgroup, including: * You can't detect if the delegate will outlive the function that created it (the Halting Problem bites you, even if you have access to all of the source). * It is sometimes ambiguous whether a given delegate wants a copy of the stack variables, or the original. Consider this snippet: void foo() { for(int i=0; i<10; i++) register(delegate int() { return i; }); exec(); } int delegate()[] registrationList; void register(int delegate() dg) { registrationList ~= dg; } void exec() { foreach(int delegate() dg; registrationList) writefln("value of this one is: ",dg()); } Now, in the code above, is each delegate supposed to get its own copy of i? Or do they share it? I'm in favor of an explicit syntax because it explicitly makes clear what the programmer intended to happen.
Aug 30 2006
Russ Lewis wrote:* You can't detect if the delegate will outlive the function that created it (the Halting Problem bites you, even if you have access to all of the source).Ok thats bad it rules out possible optimization and it become a question of of how efficient the delegates is going to bee. If the copy performance is bad maybe an explicit syntax is needed (i would propose the extra syntax is applied to the delegate instead of the data thou (bad example: have two types delegate and copying_delegate) as data can come from many different places but the function or literal is only made into a delegate once) Other idea: void foo(){} auto a=&foo;//works like now auto b= foo;//creates a heap copy of all variable the delegate uses (and each delegate gets its own instance (in the case of references it is of course the references that is copied not the data))* It is sometimes ambiguous whether a given delegate wants a copy of the stack variables, or the original. Consider this snippet: ... Now, in the code above, is each delegate supposed to get its own copy of i? Or do they share it?My proposal was that every delegate got its own copy. (it still may bee a bad proposal)I'm in favor of an explicit syntax because it explicitly makes clear what the programmer intended to happen.I also like explicit syntax until i tried to program in sml. If you haven't used sml try it I became a much better programmer only by using it a few weeks at a university course. /Johan
Aug 31 2006