Anonymous Delegates

Nick Sabalausky a at a.a
Mon Jun 16 14:29:33 PDT 2008


"Nick Sabalausky" <a at a.a> wrote in message 
news:g36kpk$15rb$1 at digitalmars.com...
> "Jason House" <jason.james.house at gmail.com> wrote in message 
> news:g36f18$lmr$1 at digitalmars.com...
>> Nick Sabalausky Wrote:
>>> In D1 and D2, what happens if you do something like this:
>>>
>>> class MyClass
>>> {
>>>     int delegate() callback;
>>>
>>>     void registerCallback(int delegate() callback)
>>>     {
>>>         this.callback = callback;
>>>     }
>>>
>>>     void display()
>>>     {
>>>         writefln("{0}", callback());
>>>     }
>>> }
>>>
>>> void foo()
>>> {
>>>     int val;
>>>     auto c = new MyClass();
>>>
>>>     val = 1;
>>>     c.registerCallback({ return val; })
>>>
>>>     val = 2;
>>>     c.display();  // Does this display "1" or "2"?
>>> }
>>>
>>> In D1 and D2, does that display "1" or "2"?
>>
>> It will print "2".  The internal context pointer refers to the stack 
>> frame from foo.
>> When the delegate is called, it'll look up val and find the value of 2. 
>> If you want
>> to get the value of 1, you'll need to bind val to the call... or find a 
>> way to make
>> capturing a variable by value work for you.
>
> I see. The talk about D2's closures creating a copy of the stack frame 
> made me wonder if that meant anonymous delegates *normally* acted on a 
> copy of the original stack frame (would have printed "1") or on the actual 
> stack frame itself (prints "2").
>
>> I don't remember if full closures are part of the latest dmd v1 compiler 
>> or if it's just dmd v2.
>
> According to the docs, full closures are D2-only.
>
> In the section "Delegates, Function Pointers, and Closures":
>
> D1 docs: http://www.digitalmars.com/d/1.0/function.html
> "The stack variables, however, are not valid once the function declaring 
> them has exited, in the same manner that pointers to stack variables are 
> not valid upon exit from a function:"
>
> D2 docs: http://www.digitalmars.com/d/2.0/function.html
> "The stack variables referenced by a nested function are still valid even 
> after the function exits (this is different from D 1.0). This is called a 
> closure. Returning addresses of stack variables, however, is not a closure 
> and is an error."
>
>>
>>
>>> As long as I'm asking about delegate stuff, something else I've been
>>> wondering too: I know this following syntax for calling a function isn't
>>> supported, but is there any technical reason preventing it from being
>>> possible?:
>>
>> I believe converting from function to delegate is no problem, but the
>> reverse is.  I believe functions exist for compatibility with C where
>> just a function pointer is passed in.
>
> That's not what I was referring to. I meant that if you have a function 
> that takes a delegate as a paramater, then it would be nice (if it would 
> even be possible for the language to allow this) to rewrite a call to that 
> function like this:
>
> // From this:
> // (Current method of calling, ugly)
> repeat(7,
> {
>    writefln("Calling Callback");
> });
>
> // To this (Syntactical sugar):
> // (Not currently allowed, but is it possibly doable?
> // Much nicer-looking.)
> repeat(7)
> {
>    writefln("Calling Callback");
> }
>
>

Although, come to think of it, if member-function-syntax (is that what it's 
called?) ever gets expanded from arrays to all types, then you'd probably be 
able to do something like this:

{
   writefln("Calling Callback");
}.repeat(7);


Which still isn't quite as nice, but it's (arguably) an improvement over the 
current style. Although, it would require repeat()'s paramaters to be 
defined in the opposite order (unless the "repeat(7){}" syntax *didn't* 
require the delegate to be the last param. Or if it just simply required the 
delegate to be the first param *instead* of requiring it to be the last 
param as I had originally proposed.)

I guess my main point is that I *love* the power that delegates give to D 
(ex: Easy map/reduce in a C-style language, yay!), but I'm jealous of the 
incredibly clean syntax that other languages (like ruby and python) provide 
for their anonymous delegates. 





More information about the Digitalmars-d mailing list