Suggestion: "new delegate" - delegates useable outside of the nesting function scope
Burton Radons
burton-radons at smocky.com
Sat Jun 3 04:50:04 PDT 2006
Walter Bright wrote:
> Burton Radons wrote:
>
>> Walter Bright wrote:
>>
>>> Unfortunately, it's quite a bit more work than that. You have to copy
>>> all the frames of the lexically enclosing functions, too. Then you
>>> have the issue of updates to the framed variable copies not being
>>> reflected in the stack variables. Then there's the problem of things
>>> like:
>>>
>>> int x;
>>> int* px = &x;
>>
>>
>> Good points (I forgot about multiple nesting - did I ever compliment
>> you for putting that in with the first release containing nested
>> functions? - but you need to chain anyway so the logic must already be
>> in there to piggyback onto), it is more work but compare it to the
>> work required when it's omitted. I have done terrible things,
>> committed sins against good engineering just because my nesting scope
>> exits, and while it hasn't had a cooling effect on me, I'm sure there
>> have been other people who have resorted to inferior Java
>> class-inheritance techniques just to get around this problem. I have
>> to admit I've done it once or twice. I was young and naive!
>>
>> Frozen variables are, of course, a feature, not a bug, and one the
>> user would opt into by using the "new" variant. We discussed this in
>> 2003. ;-) Anyway in three years and four months I haven't depended on
>> the nesting scope's variables varying once, and while I haven't really
>> wanted them to be frozen either, I've used it a few times in languages
>> which freeze the nesting scopes (like Python).
>>
>> The only really good argument against this originally, in my opinion,
>> was that it was a hidden allocation, but it's explicit like this.
>
>
> What about the px problem above? This wouldn't occur in Python which
> doesn't have pointers, but it sure happens in D.
What about if the user calls a nested function outside of the nesting
scope? They both have pitfalls.
I don't really want to mention it, but if you invert the logic it
continues to act the same without this pitfall; the only change is that
you can call the nested function outside of the nesting scope. What I
mean is that instead of just passing the delegate a pointer to the
frame, allocate the frame at the start if it or a nested scope has a
"new delegate" and use that for both the delegate and that scope:
float bar = 6;
void delegate () dg = new delegate void () { bar = 8; }
Becomes:
struct Delegate { void *self, func; }
struct Frame { float bar; Delegate dg; }
Frame *frame = new Frame;
Delegate dg;
frame.bar = 6;
frame.dg = Delegate { frame,
function void (Frame *frame) { frame.bar = 8; } };
Oh no, it's all syntax sugar! :-) The logic for doing this should mostly
already be in the code. This might be well-justified because it makes
nested functions behave consistently, and with some more effort it would
only allocate a frame containing variables the nesting functions
actually use.
More information about the Digitalmars-d
mailing list