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