I dun a DIP, possibly the best DIP ever

Manu turkeyman at gmail.com
Thu Apr 23 06:29:07 UTC 2020


On Thu, Apr 23, 2020 at 2:50 PM Steven Schveighoffer via Digitalmars-d <
digitalmars-d at puremagic.com> wrote:

> 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.
>

Yes, these are very good points. Thanks for spelling this out clearly.

In the event you want the behaviour where the template resolution is
expanded, I reckon people would expect this is the natural solution:
    alias Tup = TupleFromTemplate!(Instantiation, Args);
    (Tup + expr)...

In this expression, `Tup` would expand, because the instantiation that
created the tuple is not involved in the expression being expanded.
I have to double-check, but I expect that's precisely how the code works
naturally with no intervention. AliasSeq!() itself depends on this
behaviour to work right now in our unittests.

So, if you find yourself in a situation where you want to expand a tuple
into a template instantiation, and that instantiation resolves to a tuple
which you want to further expand, you just need to break it into 2 lines.
That will also have the nice side-effect of being much clearer to read.

> 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."
>

Yes, this reads well, thanks again. I was struggling to imagine simple
language to describe this behaviour.

> 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...
>

You're exactly correct, the first instantiation needs to be broken out to a
separate line.
Exactly. I hope this feature might motivate renewed interest in first-class
tuples, and that would improve this situation.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.puremagic.com/pipermail/digitalmars-d/attachments/20200423/9b509ae4/attachment-0001.htm>


More information about the Digitalmars-d mailing list