December 23, 2013
> 5 Algorithms from `std.typetuple` are re-written to accept non-expanding template argument lists and form base for `std.meta.` package.

Why? This seems to me like it would create duplication for nothing. These templates would do the expanding themselves?

Unless I'm mistaken, the `TemplateArgumentList`represents a packaged and convenient to use type. You only unpack it when you actually pass around the types.

If anything, this would create ambiguity. If the algorithms from typetuple accept a TemplateArgumentList, and expand it themselves, then we'd be creating ambiguity:

eg:
staticIndexOf(int, TemplateArgumentList!(int, double), int);

Produces 1? 2? 3?
I really don't know.

I think TemplateArgumentList should be handled as what it is: a *type*, and not unpackaged by clients receiving the type, but by providers of the type.
December 23, 2013
On Monday, 23 December 2013 at 13:13:13 UTC, monarch_dodra wrote:
> On Monday, 23 December 2013 at 12:25:55 UTC, Dicebot wrote:
>> On Monday, 23 December 2013 at 12:03:05 UTC, ilya-stromberg wrote:
>>> Can we add alias for `auto-expansion TypeTuple` and add link to the previous documentation like this:
>>>
>>> alias ExpandedTemplateArgumentList(T) = TemplateArgumentList!(T).expand;
>>>
>>> It looks like it can fix all objections here.
>>
>> What is this supposed to give over just using .expand directly? I have not seen a good rationale that justifies it among existing objections, probably have missed it.
>
> It allows doing a simple 's/TypeTuple/ExpandedTemplateArgumentList/'
>
> Using "TemplateArgumentList!(T).expand" is a "much" more involved transition: It's not just a simple rename.

%s/TypeTuple!(\([^)]*\))/TemplateArgumentList!(\1).expand/g ? :) Yes it will fail for few cases where there is a string with ")" among parameters, but same applies to s/TypeTuple/ExpandedTemplateArgumentList/; it still is a simple rename

Though algorithms in std.typetuple are supposed to be changed to have interface based on paced one when copied to std.meta.* so in practice it will be just s/TypeTuple/TemplateArgumentList/

Even if user attention will be needed to every single use point (which is not true), it is not justified enough objection - this is what deprecation process is for. No silent breakage is possible and this is only thing that really matters in this context.
December 23, 2013
On Monday, 23 December 2013 at 13:23:39 UTC, monarch_dodra wrote:
>> 5 Algorithms from `std.typetuple` are re-written to accept non-expanding template argument lists and form base for `std.meta.` package.
>
> Why? This seems to me like it would create duplication for nothing. These templates would do the expanding themselves?

Consistency of function signatures. Final goal is to have std.meta.* templates to be as similar as possible to their std.algorithm / std.range counterparts.

There won't be any duplication, old templates get deprecated.

> Unless I'm mistaken, the `TemplateArgumentList`represents a packaged and convenient to use type. You only unpack it when you actually pass around the types.

> If anything, this would create ambiguity. If the algorithms from typetuple accept a TemplateArgumentList, and expand it themselves, then we'd be creating ambiguity:

You only unpack (expand is proper term) it if you need to convert it to raw parameter list. You are expected to operate on it without any expansion on most other cases. Algorithms don't need to expand it either.

(And thanks Timon for an awesome "alias this" hint to achieve that)

> eg:
> staticIndexOf(int, TemplateArgumentList!(int, double), int);
>
> Produces 1? 2? 3?
> I really don't know.

Compile-time error, new `staticIndexOf` will strictly accept 2 template arguments - element and the list, similar to normal `indexOf`:

template staticIndexOf(T...)
    if ((T.length == 2) && isTemplateArgumentList!(T[1]))


> I think TemplateArgumentList should be handled as what it is: a *type*, and not unpackaged by clients receiving the type, but by providers of the type.

It does not need to expanded at all in most cases :)
December 23, 2013
On Monday, 23 December 2013 at 11:58:06 UTC, Dicebot wrote:
> Also having both types at the same time will cause difficulties with template algorithms currently present in std.typetuple - having some defined in terms of raw argument list and others in terms of packed TemplateArgumentList is just another learning curve damage.

OK, I convinced. It's definetly bad to have both `auto-expansion TypeTuple` and `TemplateArgumentList without auto-expansion` template algorithms.
So, I totally agree with this DIP, we need only `TemplateArgumentList without auto-expansion`.

BTW, I was very surprised when I saw the code from `std.typetuple.TypeTuple`:

alias TL = TypeTuple!(int, double);

alias Types = TypeTuple!(TL, char);
static assert(is(Types == TypeTuple!(int, double, char)));

It's definitely better to have `.expand` property:

alias Types = TypeTuple!(TL.expand, char);
December 23, 2013
On Monday, 23 December 2013 at 11:59:34 UTC, Dicebot wrote:
> On Monday, 23 December 2013 at 11:50:08 UTC, Timon Gehr wrote:
>> This misunderstanding arose because the name of the construct is misleading.
>
> Can explain this a bit? What makes one miss distinction between language term and library type? (Hint: latter is denoted by CamelCase ;))

Language exists by itself, library feature is composed from language features and, as it happens often, they can interact in unexpected/unforseen/broken way.

Take typedef and Typedef for example (bearophile often posts shortcommings of the latter). Irrespective of whether each of them is good/bad, this is a clear example of differences between language feature and library feature.

Personally I am upset when I get some weird Phobos structure which simulates language feature, rathen then having feature in the language in first place.
December 23, 2013
On Monday, 23 December 2013 at 13:41:07 UTC, Maxim Fomin wrote:
> On Monday, 23 December 2013 at 11:59:34 UTC, Dicebot wrote:
>> On Monday, 23 December 2013 at 11:50:08 UTC, Timon Gehr wrote:
>>> This misunderstanding arose because the name of the construct is misleading.
>>
>> Can explain this a bit? What makes one miss distinction between language term and library type? (Hint: latter is denoted by CamelCase ;))
>
> Language exists by itself, library feature is composed from language features and, as it happens often, they can interact in unexpected/unforseen/broken way.
>
> Take typedef and Typedef for example (bearophile often posts shortcommings of the latter). Irrespective of whether each of them is good/bad, this is a clear example of differences between language feature and library feature.
>
> Personally I am upset when I get some weird Phobos structure which simulates language feature, rathen then having feature in the language in first place.

I completely agree with that and would absolutely love to see tuples of all forms as first class language citizens re-designed from scratch with more consistency in mind (even made one proposal back then). But it is simply not an available options right now. I am not trying to create anything good with this DIP - just something minimally practical to work with.

But that does not answer the question how one may confuse library type with matching language feature - I don't remember anyone confusing the very same typedef / Typedef pair, for example.
December 23, 2013
On Monday, 23 December 2013 at 13:31:36 UTC, Dicebot wrote:
> On Monday, 23 December 2013 at 13:23:39 UTC, monarch_dodra
>> eg:
>> staticIndexOf(int, TemplateArgumentList!(int, double), int);
>>
>> Produces 1? 2? 3?
>> I really don't know.
>
> Compile-time error, new `staticIndexOf` will strictly accept 2 template arguments - element and the list, similar to normal `indexOf`:
>
> template staticIndexOf(T...)
>     if ((T.length == 2) && isTemplateArgumentList!(T[1]))

Ok... Then that'll break existing code that doesn't even *use* TypeTuple... Seems lose-lose to me :/

In any case, let me re-write my question it as:

staticIndexOf(int, TemplateArgumentList!(TemplateArgumentList!(int, double), int));

This time, its legal, right? What result does it create? Only the "outer" TAL gets auto-expanded, right? Expanding the inner one would seem wrong to me.

With that said, I can only image that the implementation of templates that simply recurse would become very hard to imlement.

I see value in having a packed type with explicit auto-expand, but I don't really see why it should replace the language's built-in variadic type list.
December 23, 2013
On 2013-12-23 01:39:24 +0000, "Dicebot" <public@dicebot.lv> said:

> http://wiki.dlang.org/DIP54
> 
> This is follow-up of several hot discussion threads that have happened several months ago. It has become pretty clear that there is no good way out of existing situation and least bad needs to be picked just to move forward (because it still be better than current horrible one)
> 
> Linked proposal was discussed in short e-mail conversation with Andrei (with silent observation with Walter) and is mostly pre-approved. I am interested in general opinion of community and suggestions for any smaller tweaks before starting to work on pull requests.
> 
> Thanks for your attention.

I do like this DIP.

I used to prefer auto-expanding, but working with C++11 templates convinced me otherwise. This is coming from someone who implemented a crazy function forwarding scheme for the template-based D/Objective-C bridge (not to confuse with the D/Objective-C compiler hack that came later).

That said, it'd be nice if the language reference and the compiler errors related to the language-level "tuple" used a different name than tuple too.

-- 
Michel Fortin
michel.fortin@michelf.ca
http://michelf.ca

December 23, 2013
Disclaimer: I am a newbie and I have *almost* understood the difference between built-in tuples, Tuple and TypeTuple. Almost. I'll have to get back to you on that. I also have some bad history with auto-expansion from my work with bash scripts, but that's for me and my therapist.

On Monday, 23 December 2013 at 11:08:26 UTC, Andrej Mitrovic wrote:
> We always seem to forget that all newbies will eventually become
> experienced current users. Current (experienced) users need a little
> respect as well, not everything has to be tailored to the next batch
> of newbies by breaking existing users' code. Documentation and
> tutorials are the solutions here.

This assumes that said newbies stick with the language instead of moving on to something with a better-paved learning curve. Hyperbole analogy: I'd love to be able to play the violin, but to my hands the threshold is nigh insurmountable, despite textbooks showing me how.

Excuse the argument from authority, but I seem to recall that Andrei and/or Walter suggesting that D's focus should now be on stability and avoiding breaking changes -- except where such make code *right*. To my naïve eyes, it seems like we could be preserving entropy where we're currently not, but then I don't fully grasp to what extent it would break existing code.

(As an aside, I'd love for built-in tuples not to implicitly expand either. Maybe this is one of those things I can achieve using functionality surrounding said other tuples I don't understand yet, as an inverse to an .expand property. void foo(alias fun, Args...)(Args args) { fun(args.raw); /* or unexpanded or other UFCS call */ } )
December 23, 2013
On Monday, 23 December 2013 at 13:50:26 UTC, monarch_dodra wrote:
> Ok... Then that'll break existing code that doesn't even *use* TypeTuple... Seems lose-lose to me :/

Yes, this DIP defines breaking transition that requires user action at some point. It is expected and approved by Andrei - we agreed that existing situation is even worse. But std.typetuple will remain as-is during deprecation process so there will be lot of time to do the change.

> In any case, let me re-write my question it as:
>
> staticIndexOf(int, TemplateArgumentList!(TemplateArgumentList!(int, double), int));
>
> This time, its legal, right?

Yes. It is similar to indexOf(42, [ [ 42, 43 ], 42 ]) (forgetting about not being able to define such array type ;))

> What result does it create?

1

> Only the "outer" TAL gets auto-expanded, right?

Neither. But if you want to expand inner to create monotone list, you can do it explicitly:

staticIndexOf(int, TemplateArgumentList!(TemplateArgumentList!(int, double).expand, int));

// result is 0

> With that said, I can only image that the implementation of templates that simply recurse would become very hard to imlement.

Can you give an example? I suspect you may over-complicate things a bit :)

> I see value in having a packed type with explicit auto-expand, but I don't really see why it should replace the language's built-in variadic type list.

It does not replace built-in one. This DIP does not touch language itself at all and it is stated several times. Only thing which gets replaced is std.typetuple in Phobos and documentation.