Combining Delegate and Functions

Eric Poggel dnewsgroup at yage3d.net
Fri Jul 3 12:36:23 PDT 2009


Jarrett Billingsley wrote:
> On Tue, Jun 30, 2009 at 9:21 PM, Eric Poggel<dnewsgroup at yage3d.net> wrote:
> 
>> I don't have D2 installed, but the above fails to compile in d1
>> (non-constant expression __dgliteral1).  I've also always found the above
>> syntax confusing, on the left we have "int delegate" and on the right,
>> "delegate int".  Perhaps it should always be "int delegate", and whether a
>> function body is present determines whether the expression is a type or an
>> anonymous function.  "int delegate" is also similar to how other functions
>> are defined, since "delegate" simply replaces the function name, and it's
>> similar to other languages, such as ECMA script v4 (ActionScript 3)
> 
> It would make parsing expressions prohibitively difficult.  Consider:
> 
> func(X); // X is just a name
> func(X[]); // X[] is a whole-array slice
> func(X[] delegate() { return new X[5]; }); // ughh
> 
> In the last case in particular, the compiler would already have parsed
> X[] as a slice expression, and then bam!  'delegate'.  Shit, now it
> has to rewrite or reparse the previous 'X[]' as a type instead of an
> expression.
> 
> Furthermore, having 'delegate' come first in the literals lets you
> skip the return type entirely with little change in the parsing:
> 
> func(delegate() { return new X[5]; });
> 
>> Perhaps also, functions should have available an arguments property that
>> would be a struct of the functions arguments, of type ParamTypeTuple!(func),
>> e.g.
>>
>> void foo(int a)
>> {       bar(foo.arguments);
>> }
>> void bar(int a)
>> {       writefln(bar.arguments.a); // writes 3
>>        writefln(a); // writes 3
>> }
>> foo(3);
>>
>> To me, this is much more straightforward than using std.stdarg when varargs
>> come into play.  Perhaps foo.closure could reference any variables captured
>> in a closure.
> 
> You're basically talking about variadic template args:
> 
> void foo(Args...)(Args args)
> {
>     writefln(args);
> }
> 
> void bar(Args...)(Args args)
> {
>     foo(args);
> }
> 
> bar(1, 2, 3); // prints 123
> 
>> Finally, in D2, was a way ever figured out to differentiate between
>> delegates and closures, so that delegates can be used w/o heap allocation?
> 
> IIRC the 'scope' attribute on a delegate function parameter makes it
> so that if you pass a delegate literal to that param, it won't be
> allocated as a closure.  But that's still rather restrictive, since it
> *forces* you to pass the closure as a parameter, which starts to get
> really ugly if the delegate you're passing is large.


I use variadic template args also, but templates are often confusing to 
new users, hence my suggestion.  Also, if you want to do something like 
what I habe below, I believe you have to resort to darker tuple magic.

void foo(int a, ...)
{       bar(foo.arguments); // also passes a
}
void bar(...)
{
}

Also, do you see any problems that would arise from replacing functions 
with delegates internally, so that no more conversions between them 
would be required?



More information about the Digitalmars-d mailing list