Jarrett Billingsley wrote:
On Tue, Jun 30, 2009 at 9:21 PM, Eric Poggel<[email protected]> 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?