On Wed, Oct 28, 2020 at 4:35 AM Andrei Alexandrescu via Digitalmars-d <digitalmars-d@puremagic.com> wrote:
Incidentally I'm working on a book chapter on C++ variadics and just
read through the standard
(https://github.com/cplusplus/draft/blob/master/papers/n4140.pdf, search
for "variadic" and "pack"). It provides a good baseline for evaluating
this proposal.

Overall: the proposal is imprecise and needs a lot more fleshing out in
order to provide an actual specification for implementation.

Abstract: should not be an executive review consisting of only one
confusing sentence ("..." is not an expression, it's punctuation or
operator). Abstract should clarify how explicit tuple expansion compares
with the existing implicit expansion.

I have no idea how to approach that in a spec.
I don't think I 'compare' with "existing implicit expansion", that might even be off-topic.

In reality, my DIP doesn't perform an 'expansion' in the terms that D might currently talk about tuple expansion. All my DIP does is to apply a transformation to a tuple. Tuple-in, tuple-out; that's not really an 'expansion' in current language terms, it's just a map transformation on the tuple itself.
I don't know how to fix this language.

* "...the mechanisms to implement them in D are awkward..." they are the
standard functional approach. The DIP should at best refrain from making
subjective evaluation. The high compile-time cost is good rationale.

I find the awkwardness to be similarly motivating as the high compile-time cost. If the CT cost is prohibitive to my program and there is no reasonable workaround, a solution like this becomes necessary, but in other cases even where there is not a high compile-time cost, I care about the awkwardness and how ugly the code is to read and write; bloaty syntax and logical indirections via shim templates often written elsewhere that I have to go and find. It's often a volume of text that overwhelms surrounding code and allows the actual point to be lost.

* The proposal does not mention things like Reverse, Sort etc., which
would need non-forward iteration to work efficiently and are not helped
by the proposal.

I don't understand the relevance of this point... can you show where iteration and tuples have overlapping semantics?

* "often reaching quadratic complexity for relatively simple operations"
-> a couple of (references to) examples would be great

I mean, `staticMap` is the poster child, and it's the least offensive example possible to write ;)

* "...expression to perform explicit tuple expansions at the expression
level, which can express..." good candidate for rephrasing

Yeah, the point made by Mr 'Q' below needs to feed into this... and I don't know how to do it.
It's not strictly an 'expression'... although it kind-of is.

I don't know spec language to deal with these syntax trees where they are not yet known to be expressions, or types, or... whatever.
The transformation (and tuples in general) exist as a point in compilation where value/type concepts are not yet relevant. They become relevant when evaluating the code that the tuple is plugged into at a later phase.
What do you call pre-determined syntax trees? What is the language to perform operations on a yet-to-be-determined 'kind' of thing?

* "a unary ... syntax" -> "s a unary ... postfix operator"

Yes.

* "(Tup*10)...  -->  ( Tup[0]*10, Tup[1]*10, Tup[2]*10 )" -> the example
does not clarify how one expression expands into multiple expressions;
this is not something that an operator does. The parens don't help - are
they required, provided for illustration...? The meaning of the
expansion (e.g. array initialization vs. function call etc) is
determined by the context of the expansion. That's why the C++ proposal
and standard focus most of the description on expansion loci.

Actually, the parens are a bug in the DIP. It should read:
  (Tup*10)...  -->  (Tup[0]*10), (Tup[1]*10), (Tup[2]*10)

I thought that should be clear. And yes, the parens are necessary because I use a bin-op in this example which have lower precedence than unary operators.

Should I write:
   (Tup*10)...  -->  AliasSeq!((Tup[0]*10), (Tup[1]*10), (Tup[2]*10 ))

I'm not sure using `AliasSeq`, which is a piece of library, is appropriate in a spec?

Again, I try to show semantic through obvious example here because the spec language I refer to above is mysterious to me.

* "C++11 implemented template parameter pack expansion with similar
semantics, and it has been a great success in the language. Coupled with
D's superior metaprogramming feature set, D users can gain even greater
value from this novel feature." -> specious argument, even if we allow
for the "great success" in C++. (Most uses of "..." in C++ are sheer
black magic and have required simplifications in C++17. NOT a success
story.) The main problem is different though. C++ parameter packs don't
enjoy /any/ other operation aside from expansion and "...".

Well... what do you want? Should I just remove that? People asked me to add it.

To add that
to the many existing operators for tuples that D has and claim it'll
just work great because it did in C++ does not stand to reason.

What operators do tuples have in D? We can slice and index them... I think that's all?
Why might you imagine this DIP would interact with tuple element indexing? Why is that significant enough to call out explicitly?

* Major bug: the "Rationale" discusses only expression, whereas
staticMap does not use expressions. It just processes tuples, which may
contain types. Types cannot appear in expressions. C++ goes to great
lengths to distinguish between template parameter packs (which may be
one of type parameter pack, value parameter pack, and template template
parameter pack) and function parameter packs (which may only be
parameter declarations). By the Rationale nothing except expressions
will be accessible to D's proposed "...". That means no staticMap for
non-valies (e.g. staticMap!(Unqual, types)), which probably wasn't the
intent of the DIP.

Yes, as mentioned above, and also by Q below, this is the critical issue with this DIP, and I have no idea how to address this.
Everywhere I use the term 'expression' is invalid, but what do I write instead?

`syntax...` <- what is 'syntax' called in spec-language? It could be any syntax tree that makes grammatical sense.

* "The implementation will explore expr" -> there's no formal definition
of "explore". The C++ spec mentions "the largest expression to the left
of the ...". Probably that would work here, too.

Also an important point... how do you imagine that phrase you reference applying here? Can you suggest a better sentence?

* "A second form shall exist which may implement a static reduce
operation with the syntax expr [BinOp] ..." What happens if the tuple is
empty?

Compile error on empty tuple. I thought that was stated in the DIP, but I missed it. It states the rules on equal length, and no tuple present, but misses empty tuple >_<

C++17 allows ... only in between operators, e.g.:

return false || ... || args == value;

I haven't specified this, because I don't believe it's necessary the same way it is in C++. This is necessary in C++ because parameter packs are barely part of the language, and painfully cumbersome to interact with. In D, if you want a limit value, I think it would be reasonable to just append a limit value to the tuple in-situ.
There has been a lot of discussion about first-class tuples in D, and in that future you'd be able to do `MyTup ~ limit`, but for now `AliasSeq!(MyTup, limit)` seems convenient enough to me that it shouldn't require that we spec a limit syntax like C++.
If it's determined in the future that we want the limit case, it can be trivially added with a follow-up DIP, but I would not add it eagerly, I believe it's unnecessary.

thus allowing the author to choose the limit value.

* The "Compliation Performance" needs to discuss how the operator
handles backward iteration.

I don't understand what you're asking about here? Tuples don't 'iterate'... I'm not aware my DIP impacts or intersects any semantics dealing with iteration that should need to be called out?

...

These are all good points. Are you opposed to this DIP? If not, would you consider collaborating on this?
I don't really know appropriate language to address some of your points. I'm convinced the DIP will fail on account of the points you make, and if I can't correct them, then it's an automatic fail, and I might as well withdraw it now to save myself the torture, and you the time destroying it in a few weeks.

Or anyone else...? This definitely needs fixing, and I don't really know how to do it.