I dun a DIP, possibly the best DIP ever

Steven Schveighoffer schveiguy at gmail.com
Thu Apr 23 04:48:54 UTC 2020


On 4/22/20 8:13 PM, Manu wrote:
> On Thu, Apr 23, 2020 at 2:10 AM Steven Schveighoffer via Digitalmars-d 
> <digitalmars-d at puremagic.com <mailto:digitalmars-d at puremagic..com>> wrote:
> 
>     On 4/22/20 11:17 AM, Manu wrote:
>      >
>      > I have thought about how to discuss this in the DIP; I describe the
>      > semantic, and what happens is what happens.
>      > This will work, and something will happen... when we implement
>      > TemplateInstance, we'll find out exactly what it is :P
>      > What I will do is show what such a nested tuple does when code
>     works in
>      > the DIP to instantiate TemplateInstances.
>      >
>      > It's basically the same thing as what you showed above with:
>      > Items[0].MemberTup, Items[1].MemberTup, ...
>      > In general, in D currently, nested tuples flatten. Evaluate from the
>      > leaf upwards. Your answer will materialise.
> 
>     I think this is more complicated than the MemberTup thing. By inference
>     of the name, MemberTup is a tuple, but only defined in the context of
>     the expanded items. There aren't any tuples for the compiler to expand
>     in there.
> 
>     A template that returns a tuple based on it's parameters is a tuple
>     with
>     or without expansion.
> 
>     F!(F!t)) is valid. It's going to return int, char, int, char, int,
>     char,
>     int, char
> 
>     F!(F!t))... what does this do?
> 
> I expect it will do this:
> 
> F!(F!t)... =>
> 
> expand for `t` (at leaf of tree):
> F!( (F!t[0], F!t[1]) )  ~= F!( (F!int, F!char) )  =>

OK, that is what I thought too (that is the most useful), but this needs 
to be explicit in the DIP.

Remember that templates can also be tuples too, so when it says " for 
any tuples present in the expression tree", it reads ambiguous.

I will bring up again something like this, which someone might expect to 
work:

alias G(T) = const(T);

alias F(T) = AliasSeq!(T, T);

alias f = F!(int);
G!(f)...; // seems cool to me
G!(F!int)...; // compiler error or works?
G!(AliasSeq!(int, char))...; // error or works?

> Spec does not say it will NOW evaluate the template and operate on the 
> result, it deals with the expression as stated.

I'm not expecting multiple expansions, but one has to remember that D is 
full of templates that create tuples, so the DIP has to say at what 
point "these tuples are generated and considered before the expansion" 
and "these are not". It seems to me you are saying only tuples that 
exist BEFORE the expression are considered. Something like that should 
be in the DIP, with appropriate examples.

> That's the expansion I would expect from that expression. So, I guess 
> the point you want to determine is that *evaluating* templates is NOT 
> part of tuple expansion.

A good way to say it, but still needs examples in the DIP to clarify. To 
elaborate, you might say:

"expansion is performed only on tuples represented by symbols in the 
expression. All template instantiations that generate tuples are 
performed after expansion is finished."

> I think that expansion is actually reasonable and 'easy' to understand. 
> There's nothing unexpected about application of the stated rules.
> Of course, I would suggest not writing code like this, unless it's 
> really clear to the reader what your intent was. There's a 
> million-and-one ways to write obscure code that does something, but 
> doesn't really help the reader along the way; this expression is one 
> such thing.

It's easy to understand, but it's also easy to expect the compiler to 
understand what you were thinking when you wrote:

foo!(AliasSeq!(int, char))...

instead of the (required) long form:

alias args = AliasSeq!(int, char);
foo!(args)...

proper tuples would make this much less painful...

-Steve


More information about the Digitalmars-d mailing list