On Sunday, 29 December 2013 at 21:41:48 UTC, Dicebot wrote:
Of course because we have damn nothing in our template
algorithm set. Those are just basics. If stuff goes as planned
std.meta.* will have template alternatives of almost all stuff
from std.range and std.algorithm. Any function from there that
takes pair of ranges or range of ranges will be subject to this
decision. Should I list them all?
Packed lists only come into play with algorithms that receive a
list of lists that can contain types (for non-types we'd be in
good shape with `toTypeTuple`). Again, I've never had a use for
this, so I expect the DIP to adequately explain the motivation
behind going to such great lengths to support it. It doesn't do
this at all. Not a single example or reference or anything.
You words about "huge maintenance cost" are pretty much as
subjective and unproved as my "it is ugly" statement. If
anything, packed lists result in easier maintenance as they
make list passing more hygienic and in line with passing of any
other aliases and flattening/merging of lists explicit and
obvious. There has been one guy even in this thread who was
surprised by current behavior.
My statement assumed that existing (and maybe new) algorithms
would support *both* plain argument lists like they do now, and
packed lists.
If we instead choose only plain argument lists, no changes are
required. If we instead choose only packed lists, there is a
one-time cost to porting all the algorithms, but no extra
maintenance cost from then on out.
And built-in variadic templates will remain anyway, so question
is not "what merit auto-expanding list does have" but "what
merit auto-expanding list does have as an extra library type".
I don't think it's correct nor useful to refer to template
argument lists as "types", or that std.typetuple.TypeTuple is
somehow a type. A packed list implemented through a *struct* with
AliasThis would be a type, although a pretty terrible one. Its
use as a type would be valid but complete nonsense; it's only a
struct for its function as a namespace.
New multilist utilities added are expected to use `Pack`s (I
am still convinced that using nested templates for that is
ugly)
I don't consider "it's ugly" with no elaboration a valid
argument.
"It is completely out of line with existing function signatures
for non-template algorithms that it mirrors"
It's essentially currying, which is no surprise considering the
functional nature of templates. It also has the advantage of
allowing "partial template instantiation".
I also don't think there's any point in emulating manipulation of
values for manipulation of types when functions and templates are
in reality different.
"Use for declaring an expression list from a type list" - not
common at all and pretty much never used by anyone but very
experienced library writers (it is rather arcane thing on its
own)
It's *the* most common use of variadic templates, hands down:
---
void write(Args...)(Args args)
{
// `Args` is a type list, `args` is an expression list
}
---
"Use for initalizing other expressions lists with an expression
list" - should require expansion anyway because it is how
std.typecons.Tuple works
Consider this kind of code, which I often see in the wild, even
by relative beginners who are eager to learn about D's generative
abilities:
---
ParameterTypeTuple!fun args;
foreach (ref arg; args)
arg = strArgs.parse!(typeof(arg));
fun(args);
---
Packed lists would just be in the way here. If you try to fix
that problem with AliasThis, you gain another problem -
especially if `fun` is a function template!
"Use in static foreach" - works with alias this
The AliasThis approach has issues. We need more experience with
it if we want to pursue packed lists.
"Use in special expressions that operate on types, such as `is`,
`typeof` and `typeid`" - any code that does on expanded lists
right now is completely broken and must be re-written according
to existing spec. Exanded argument list is not a valid type for
any of those entities (despite it is magically accepted).
Indexing single element works with "alias this".
They are documented on the tuple page and it is not "magical"
that it is accepted; it is deliberate. It is clearly illustrated
in one of the examples there, and the behaviour is definitely
useful. Again, don't confuse template argument lists for being
"types". That's not a useful definition for anyone.
"Use as a public alias in a library interface, leaving the
specifics of application to the user" - irrelevant to expansion
as you mention on your own
It's just for completeness. I believe the list is complete now
that you have added indexing.
Yep, this is an attempt to somewhat compensate bad language
decision by more hygienic library solution. Your rationale is
based on assumption that language feature is OK an anything
else should be based on it. But it is not OK in general, only
for very few library writers.
I think it's OK, also for beginners. If you want to convince
people that it's not, you need to come up with a solid rationale
that illustrates how the language semantics are bad. Again, I
believe we have a naming and documentation problem.
My key point is that common and basic use cases that are likely
to appear in casual code should take priority over needs of
library writers as latter are ready to deal with extra
complexity pretty much by definition. I am personally ready to
do it despite it will cause problems/inconvenience for my own
code. simply because it is bigger than that. Your arguments
about use cases are very biased towards that librar'ish usage.
We don't have any hard stats here so someone else needs to make
the judgement but I think you are mistaken in how widely
applicable it is.
My arguments are rooted in language semantics (that you are
desperately fighting). They apply to all users of template
argument lists, however casual.
expansion is the only use case of template argument lists.
You keep repeating it and have not shown strong evidences for
it so far. Core use cases for template arguments in common user
code is indexing and iteration which can "just work" for packs
too.
I listed a complete list of all use cases of template argument
lists, and they all require expansion. I think that's strong
evidence.
Yes, static foreach and indexing can work with AliasThis, but
again, the struct + AliasThis has issues (and how is indexing a
template argument list a casual use, btw?).
If we won't address this question at the same time it will pop
up again once std.meta.* pull request will start to appear and
deferring decision to that point will just force users to
adjust same code twice. That does not sound good.
Better than predicating the entire conversation on the unproven
thesis that std.meta.* will not only be accepted, but will
completely eclipse all use of template argument lists, which I
don't think it will even come close to do. Attempting to do so,
will - as I've argued - harm (all) users of template argument
lists in the common case.