www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - DIP54 : revamp of Phobos tuple types

reply "Dicebot" <public dicebot.lv> writes:
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.
Dec 22 2013
next sibling parent reply Timon Gehr <timon.gehr gmx.ch> writes:
On 12/23/2013 02:39 AM, Dicebot wrote:
 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.
How is this going to be implemented? In a similar way as this?: https://d.puremagic.com/issues/show_bug.cgi?id=11804 "Why that weird long name, `TemplateArgumentList` A: Because it is exactly what it is." Well, unfortunately template argument lists auto-expand... :o)
Dec 22 2013
parent reply "Dicebot" <public dicebot.lv> writes:
On Monday, 23 December 2013 at 01:53:57 UTC, Timon Gehr wrote:
 How is this going to be implemented? In a similar way as this?:
 https://d.puremagic.com/issues/show_bug.cgi?id=11804
Without `alias this` part (that would destroy "no auto expansion" part unless I miss something). Also I am still uncertain about implementing it as templated struct or just raw template - both have own merits and flaws, will make better comparison in process.
Dec 22 2013
parent reply Timon Gehr <timon.gehr gmx.ch> writes:
On 12/23/2013 03:28 AM, Dicebot wrote:
 On Monday, 23 December 2013 at 01:53:57 UTC, Timon Gehr wrote:
 How is this going to be implemented? In a similar way as this?:
 https://d.puremagic.com/issues/show_bug.cgi?id=11804
Without `alias this` part (that would destroy "no auto expansion" part
No.
 unless I miss something).
std.typecons.Tuple also uses alias this.
 Also I am still uncertain about implementing
 it as templated struct or just raw template - both have own merits and
 flaws, will make better comparison in process.
I think alias this is the only way to use the static index operator.
Dec 22 2013
parent "Dicebot" <public dicebot.lv> writes:
On Monday, 23 December 2013 at 02:42:01 UTC, Timon Gehr wrote:
 On 12/23/2013 03:28 AM, Dicebot wrote:
 On Monday, 23 December 2013 at 01:53:57 UTC, Timon Gehr wrote:
 How is this going to be implemented? In a similar way as 
 this?:
 https://d.puremagic.com/issues/show_bug.cgi?id=11804
Without `alias this` part (that would destroy "no auto expansion" part
No.
Very promising then, didn't know about it. Assuming no nasty side-effects will be found it sounds like the way to go.
Dec 22 2013
prev sibling next sibling parent reply "Jakob Ovrum" <jakobovrum gmail.com> writes:
On Monday, 23 December 2013 at 01:39:26 UTC, Dicebot wrote:
 http://wiki.dlang.org/DIP54
Are you seriously suggesting we change the auto-expanding behaviour of template argument lists? This is going to cause the biggest code breakage since D2, for the niche benefit of having lists that don't automatically expand. This DIP makes several unfounded assumptions. It assumes that the semantics of template argument lists are inherently hard to learn, and that removing the auto-expanding aspect will make them easier to learn. It assumes that non-auto-expanding lists provide a significant usability boost, and claims that it enables previously impossible algorithms. It claims to be a compromise derived from several previous discussions (without citing any), but the only consensus I remember is that we have a naming problem. I don't remember anyone but you asking for non-expanding lists *in the language*, which I regard a red herring. I see no proof provided for any of this. I hate to say this, but it looks a lot like your personal agenda against auto-expanding lists is tacked onto and conflated with the naming problem, which I think is disingenuous.
 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)
I don't agree. I think we'd be in good shape just by fixing the naming problem, which is a much less controversial change.
 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.
Please don't pull the argument-by-authority card. Private conversations that affect all of us like this need to die in a fire. We should consider this kind of thing the equivalent of tainted evidence.
Dec 22 2013
next sibling parent "H. S. Teoh" <hsteoh quickfur.ath.cx> writes:
On Mon, Dec 23, 2013 at 02:46:38AM +0000, Jakob Ovrum wrote:
 On Monday, 23 December 2013 at 01:39:26 UTC, Dicebot wrote:
http://wiki.dlang.org/DIP54
Are you seriously suggesting we change the auto-expanding behaviour of template argument lists? This is going to cause the biggest code breakage since D2, for the niche benefit of having lists that don't automatically expand.
[...] Where did you get that idea from? My understanding from reading the DIP is that we just replace std.typecons.TypeTuple, which has this definition: template TypeTuple(T...) { alias TypeTuple = T; } with std.meta.list, which has this definition: template list(T...) { alias expand = T; } along with the requisite documentation changes, deprecation of TypeTuple, migration of Phobos code to use std.meta.list, etc.. Nothing changes in the language itself. Changing the language itself will basically break almost the entire Phobos, and pretty much anything that uses variadic template arguments in non-trivial ways in user code. I don't see that ever happening in D2. T -- Life is unfair. Ask too much from it, and it may decide you don't deserve what you have now either.
Dec 22 2013
prev sibling parent reply "Dicebot" <public dicebot.lv> writes:
On Monday, 23 December 2013 at 02:46:40 UTC, Jakob Ovrum wrote:
 This DIP makes several unfounded assumptions. It assumes that 
 the semantics of template argument lists are inherently hard to 
 learn,
Hard? No. Complicated - yes, I see wrong assumptions being made all the time. But this is language failure and is not directly related to this DIP.
 and that removing the auto-expanding aspect will make them 
 easier to learn.
I don't say that. I say that it will allow to avoid introduction of _third_ tuple type into Phobos which would have makes things even harder to learn.
 claims that it enables previously impossible algorithms.
Algorithm that operates on variadic amount of template argument lists can't be expressed with TypeTuple behavior.
 It claims to be a compromise derived from several previous 
 discussions (without citing any),
That I admit of my failure but I was not able to find discussions in archive in time. I will do it and add those as links eventually.
 I hate to say this, but it looks a lot like your personal 
 agenda against auto-expanding lists is tacked onto and 
 conflated with the naming problem, which I think is 
 disingenuous.
Well, if you will actually find those threads, you will see that I was in favor of auto-expanding behavior ;) It was Andrei who has convinced me.
 I don't agree. I think we'd be in good shape just by fixing the 
 naming problem, which is a much less controversial change.
We can't afford to add even more "tuple" types in library.
 Please don't pull the argument-by-authority card. Private 
 conversations that affect all of us like this need to die in a 
 fire. We should consider this kind of thing the equivalent of 
 tainted evidence.
I am merely implying that this is not yet another random DIP that will hang for eternity and that this discussion will have some practical consequences in very nearby future, whatever the final outcome is.
Dec 22 2013
parent reply "Jakob Ovrum" <jakobovrum gmail.com> writes:
On Monday, 23 December 2013 at 03:17:27 UTC, Dicebot wrote:
 Hard? No. Complicated - yes, I see wrong assumptions being made 
 all the time. But this is language failure and is not directly 
 related to this DIP.
I don't think it's obvious that it's a language failure.
 I don't say that. I say that it will allow to avoid 
 introduction of _third_ tuple type into Phobos which would have 
 makes things even harder to learn.
It wouldn't be the third tuple type, it would be the second type of list.
 Algorithm that operates on variadic amount of template argument 
 lists can't be expressed with TypeTuple behavior.
They would be amply supported by using the second type of list. Still, there are no examples of such algorithms presented by the DIP. Without substantial evidence, they are niche at best or virtually non-existent at worst (though I'm sure it's the former). In either case, I don't think they warrant conflation with auto-expanding lists.
 Well, if you will actually find those threads, you will see 
 that I was in favor of auto-expanding behavior ;) It was Andrei 
 who has convinced me.
Then I apologize, and retract my comment.
 We can't afford to add even more "tuple" types in library.
One tuple and two compile-time lists - where the auto-expanding one covers the vast majority of use cases - doesn't sound at all bad. I think we can conclude that auto-expanding lists cover the vast majority of cases on the basis that all of Phobos and virtually all other libraries use auto-expanding lists to great effect without interface contrivances. My argument comes down to the fact that I think the issue of auto-expansion is orthogonal to the naming issue; yes, I acknowledge it would be beneficial to solve both at once, but such an integrated solution is predicated on the fact that auto-expansion is an issue in the first place, which I don't think the DIP addresses sufficiently. I *do* think it does sufficiently address the fact that the current naming scheme is a problem.
Dec 22 2013
next sibling parent reply "Dicebot" <public dicebot.lv> writes:
On Monday, 23 December 2013 at 03:45:07 UTC, Jakob Ovrum wrote:
 We can't afford to add even more "tuple" types in library.
One tuple and two compile-time lists - where the auto-expanding one covers the vast majority of use cases - doesn't sound at all bad.
I think this is the root cause of disagreement and everything else is just a consequence from it. I still remember my initial confusion when trying to figure out this part of the language - it wasn't really related to naming but more about trying to understand what intended use cases does each entity have. It is all natural once you start to casually use it but not before. If both types are present in the library in the same time we will need to explain why both are needed, what is the difference, when each is expected to be used and so on. It is a serious risk of cognitive overload considering one is already expected to get some grasp about native template argument lists and how those can be used. If there is only one type, it becomes considerably more simple - just use it and once you get familiar with it deep enough to need expansion behavior - `.expand` will be an expected discovery. 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. What is even more important - auto-expanding lists simply don't have any important value to preserve on their own as they are already present in form of raw template arguments and `.expand`. This was what made me change opinion on this topic back then.
Dec 23 2013
parent "ilya-stromberg" <ilya-stromberg-2009 yandex.ru> writes:
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);
Dec 23 2013
prev sibling parent reply "bearophile" <bearophileHUGS lycos.com> writes:
Jakob Ovrum:

 One tuple and two compile-time lists - where the auto-expanding 
 one covers the vast majority of use cases - doesn't sound at 
 all bad.
Plus built-in syntax to unpack tuples in various situations. Bye, bearophile
Dec 23 2013
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 12/23/13 4:07 AM, bearophile wrote:
 Jakob Ovrum:

 One tuple and two compile-time lists - where the auto-expanding one
 covers the vast majority of use cases - doesn't sound at all bad.
Plus built-in syntax to unpack tuples in various situations.
I don't think "various situations" is a good idea. It often does make code shorter. But it means more rules to be defined, implemented, and taught. Andrei
Dec 23 2013
parent reply "bearophile" <bearophileHUGS lycos.com> writes:
Andrei Alexandrescu:

 I don't think "various situations" is a good idea. It often 
 does make code shorter. But it means more rules to be defined, 
 implemented, and taught.
Here I have written "various situations" because I have given a list of those "various situations" in past posts. I think the semantics is sufficiently natural, simple, and it's same for all those cases. I think the main problem in D is syntactic.
 It often does make code shorter.
It also avoids the programmer to think about useless details, leaving more brain for more important things. Assigning the fields to variables like this: const uselessTmp = foo(); immutable something = uselessTmp[0]; immutable secondThing = uselessTmp[1]; const theLast = uselessTmp[2]; is as efficient as leaving that to the compiler. Bye, bearophile
Dec 23 2013
parent Dmitry Olshansky <dmitry.olsh gmail.com> writes:
24-Dec-2013 04:57, bearophile пишет:
 Andrei Alexandrescu:
 It often does make code shorter.
It also avoids the programmer to think about useless details, leaving more brain for more important things. Assigning the fields to variables like this: const uselessTmp = foo(); immutable something = uselessTmp[0]; immutable secondThing = uselessTmp[1]; const theLast = uselessTmp[2]; is as efficient as leaving that to the compiler.
Agreed. IMHO destructuring of structs, tuples and arrays is something we ought to have at some point. Something not unlike ECMA Script: http://wiki.ecmascript.org/doku.php?id=harmony:destructuring http://wiki.ecmascript.org/doku.php?id=proposals:destructuring_assignment
 Bye,
 bearophile
-- Dmitry Olshansky
Dec 24 2013
prev sibling next sibling parent reply "H. S. Teoh" <hsteoh quickfur.ath.cx> writes:
On Mon, Dec 23, 2013 at 01:39:24AM +0000, Dicebot wrote:
 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 approve of this proposal. Even though it's not 100% ideal, it is still better than the current situation. People who want auto-expanding template argument lists can still do this: template ExpandingArgList(T...) { alias ExpandingArgList = T; } Just like we have now. T -- If you look at a thing nine hundred and ninety-nine times, you are perfectly safe; if you look at it the thousandth time, you are in frightful danger of seeing it for the first time. -- G. K. Chesterton
Dec 22 2013
parent reply "Jakob Ovrum" <jakobovrum gmail.com> writes:
On Monday, 23 December 2013 at 02:55:57 UTC, H. S. Teoh wrote:
 People who want auto-expanding template argument lists can 
 still do
 this:
It's not perfectly clear, but it looks to me that the DIP suggests removing the auto-expanding property of template argument lists.
Dec 22 2013
parent reply "Dicebot" <public dicebot.lv> writes:
On Monday, 23 December 2013 at 03:00:11 UTC, Jakob Ovrum wrote:
 On Monday, 23 December 2013 at 02:55:57 UTC, H. S. Teoh wrote:
 People who want auto-expanding template argument lists can 
 still do
 this:
It's not perfectly clear, but it looks to me that the DIP suggests removing the auto-expanding property of template argument lists.
No, it would have changed language feature which is deeply integrated with lot of stuff and thus is untouchable. This proposal is only about Phobos and documentation.
Dec 22 2013
next sibling parent "H. S. Teoh" <hsteoh quickfur.ath.cx> writes:
On Mon, Dec 23, 2013 at 03:02:48AM +0000, Dicebot wrote:
 On Monday, 23 December 2013 at 03:00:11 UTC, Jakob Ovrum wrote:
On Monday, 23 December 2013 at 02:55:57 UTC, H. S. Teoh wrote:
People who want auto-expanding template argument lists can still do
this:
It's not perfectly clear, but it looks to me that the DIP suggests removing the auto-expanding property of template argument lists.
No, it would have changed language feature which is deeply integrated with lot of stuff and thus is untouchable. This proposal is only about Phobos and documentation.
That's what I thought. To make template argument lists non-expanding would basically require a rewrite of the compiler, since it's deeply integrated into compiler internals right now. And it would result in a language so foreign to existing user code that it might well be D3. It *might* be a possibility in the far future when we're ready to talk about D3, but that doesn't seem likely for the next 10 years (at least). T -- It won't be covered in the book. The source code has to be useful for something, after all. -- Larry Wall
Dec 22 2013
prev sibling parent reply Timon Gehr <timon.gehr gmx.ch> writes:
On 12/23/2013 04:02 AM, Dicebot wrote:
 On Monday, 23 December 2013 at 03:00:11 UTC, Jakob Ovrum wrote:
 On Monday, 23 December 2013 at 02:55:57 UTC, H. S. Teoh wrote:
 People who want auto-expanding template argument lists can still do
 this:
It's not perfectly clear, but it looks to me that the DIP suggests removing the auto-expanding property of template argument lists.
No, it would have changed language feature which is deeply integrated with lot of stuff and thus is untouchable. This proposal is only about Phobos and documentation.
This misunderstanding arose because the name of the construct is misleading.
Dec 23 2013
parent reply "Dicebot" <public dicebot.lv> writes:
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 ;))
Dec 23 2013
next sibling parent reply "Maxim Fomin" <maxim maxim-fomin.ru> writes:
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.
Dec 23 2013
next sibling parent "Dicebot" <public dicebot.lv> writes:
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.
Dec 23 2013
prev sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 12/23/13 5:41 AM, Maxim Fomin wrote:
 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.
It's a fine line to thread. Erring on either side is easy and with bad consequences. Andrei
Dec 23 2013
parent reply "H. S. Teoh" <hsteoh quickfur.ath.cx> writes:
On Mon, Dec 23, 2013 at 04:30:14PM -0800, Andrei Alexandrescu wrote:
 On 12/23/13 5:41 AM, Maxim Fomin wrote:
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.
It's a fine line to thread.
<grammarnazi> *tread. </grammarnazi>
 Erring on either side is easy and with bad consequences.
[...] Personally, I'm for simplifying the core language and moving non-essentials out to the standard library -- *provided* that said standard library feature (1) doesn't suffer from overly ugly syntax due to not being part of the language proper, and (2) isn't defective in functionality in some way that a built-in wouldn't be. Building too many things into the language is bad because it makes the language (1) more complex than it needs to be, (2) harder to learn as a result, and (3) require way too much effort to implement (or implement *correctly*)(*cough*C++*cough*) -- you end up with "language is defined by quirky compiler behaviour" rather than "language follows spec". T -- I think the conspiracy theorists are out to get us...
Dec 23 2013
parent reply "bearophile" <bearophileHUGS lycos.com> writes:
H. S. Teoh:

 Personally, I'm for simplifying the core language and moving
 non-essentials out to the standard library
How do you define "essential"? - Frequently used; - The compiler can compile it as efficiently as handwritten code; - Has a sufficiently clean semantics, that is most times the one that's desired; - You can't (yet) implement its main purposes with library-code; - Sufficiently important. - etc. Bye, bearophile
Dec 23 2013
parent "H. S. Teoh" <hsteoh quickfur.ath.cx> writes:
On Tue, Dec 24, 2013 at 01:05:26AM +0000, bearophile wrote:
 H. S. Teoh:
 
Personally, I'm for simplifying the core language and moving
non-essentials out to the standard library
How do you define "essential"? - Frequently used;
I don't think 'frequently used' is sufficient to justify putting it in the core language. If a library type (1) provides the same functionality, (2) compiles to equally-efficient code, and (3) isn't overly ugly to write, then I'd go with the library type. For core language features, I consider orthogonality much more important. That is, if existing features can already do what the prospective feature can do, then it's probably better to put it in the standard library. A good candidate for inclusion in the core language is a feature that, if it were not in the language, would cause some things to be impossible to achieve (or to be achievable only with difficulty). Ideally, the core language should be as minimalistic as possible, and provide only the truly essential features that the standard library can build on. There are a lot of advantages of a small core language: easier to implement, so more likely to be bug-free; reduction of the combinatorial explosion of features that introduce many hiding places for bugs / unexpected interactions because there are too many combinations of features to test; easier to reason about; etc.. Of course, in practice you can't be overly minimalistic, otherwise it becomes painful to do simple things; the adage is, "simple things should be easy, hard things should be possible".
 - The compiler can compile it as efficiently as handwritten code;
If the library implementation can be equally efficient, then this isn't a good reason to push the feature into the core language.
 - Has a sufficiently clean semantics, that is most times the one
 that's desired;
But isn't this an issue with in-compiler implementations too? An ill-defined feature is an ill-defined feature, no matter whether it's implemented in the library or the compiler. Though I agree that if a compiler implementation has cleaner semantics than a library implementation, then the compiler implementation would be preferable.
 - You can't (yet) implement its main purposes with library-code;
This is a big reason to extend the core language, although even in this case I'd rather add only a minimal extension (not necessarily the entire feature) that makes it possible for library code to implement the feature, then put the actual implementation in the library.
 - Sufficiently important.
[...] Important as measured by what? Important features can be part of the standard library too -- that's why it's the *standard* library, after all. It's a different story, of course, if said feature can't be adequately implemented by the library, but that's nothing to do with its importance, rather it's just a matter of extending the core language just enough to be able to implement it properly. Importance doesn't necessarily dictate that the feature must be implemented in the core language in its entirety. T -- INTEL = Only half of "intelligence".
Dec 23 2013
prev sibling parent reply Timon Gehr <timon.gehr gmx.ch> writes:
On 12/23/2013 12:59 PM, 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?
(It is not a type.) "At the same time automatic expansion of `TypeTuple` is considered both unhygienic and not consistent with `std.typecons.Tuple`. Fixing it will allow some new template algorithms while still keeping "tuple" library type count at two." => the new construct will not auto-expand. "Why that weird long name, `TemplateArgumentList` A: Because it is exactly what it is. This name makes it clear that one may expect from this thing behavior similar to http://dlang.org/template.html#TemplateArgumentList" => the new construct will behave like the built-in Together this yields that the built-in will not auto-expand.
 (Hint: latter is denoted by CamelCase ;))
As is the former. :P http://dlang.org/template.html#TemplateArgumentList I think using the name TemplateArgumentList for anything other than a shallow wrapper around a template argument list does not actually improve the naming situation.
Dec 23 2013
parent reply "monarch_dodra" <monarchdodra gmail.com> writes:
On Monday, 23 December 2013 at 15:59:10 UTC, Timon Gehr wrote:
 As is the former. :P
 http://dlang.org/template.html#TemplateArgumentList


 I think using the name TemplateArgumentList for anything other 
 than a shallow wrapper around a template argument list does not 
 actually improve the naming situation.
This too also bothers me. I'd be more comfortable with (the even longer): "PackedTemplateArgumentList".
Dec 23 2013
parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 12/23/13 8:21 AM, monarch_dodra wrote:
 On Monday, 23 December 2013 at 15:59:10 UTC, Timon Gehr wrote:
 As is the former. :P
 http://dlang.org/template.html#TemplateArgumentList


 I think using the name TemplateArgumentList for anything other than a
 shallow wrapper around a template argument list does not actually
 improve the naming situation.
This too also bothers me. I'd be more comfortable with (the even longer): "PackedTemplateArgumentList".
TemplateArgumentPack Andrei
Dec 23 2013
prev sibling next sibling parent "Meta" <jared771 gmail.com> writes:
On Monday, 23 December 2013 at 01:39:26 UTC, Dicebot wrote:
 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.
Yes, this is great. Anything to take tuples a step in the right direction. I'm immensely glad that TemplateArgumentList will not have auto-expansion by default, too.
Dec 22 2013
prev sibling next sibling parent reply "John Colvin" <john.loughran.colvin gmail.com> writes:
On Monday, 23 December 2013 at 01:39:26 UTC, Dicebot wrote:
 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.
This is great. My implementation of this, recently updated: https://github.com/John-Colvin/meta-d
Dec 23 2013
parent "John Colvin" <john.loughran.colvin gmail.com> writes:
On Monday, 23 December 2013 at 09:14:46 UTC, John Colvin wrote:
 On Monday, 23 December 2013 at 01:39:26 UTC, Dicebot wrote:
 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.
This is great. My implementation of this, recently updated: https://github.com/John-Colvin/meta-d
Notes: I haven't put the new names in yet, Pack -> TemplateArgumentList (personally I prefer Pack, as it isn't the same as a template argument list) Having Pack in a template mixin is only needed for the opDispatch ufcs stuff. It could be dropped. The meta.algorithm module is incomplete compared to std.algorithm I still include Seq (i.e. TypeTuple). Sometimes a true template argument list is needed.
Dec 23 2013
prev sibling next sibling parent reply "ilya-stromberg" <ilya-stromberg-2009 yandex.ru> writes:
On Monday, 23 December 2013 at 01:39:26 UTC, Dicebot wrote:
 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.
It's great thank you. I totally agree that `TypeTuple` name is a problem, `TemplateArgumentList` looks much better. About `auto-expansion` problem: please add documentation that describes difference between `auto-expansion TypeTuple` and `TemplateArgumentList without auto-expansion`. I personally don't know any difference, probably because I didn't write too complicated meta code. Also, can we keep bouth `auto-expansion TypeTuple` and `TemplateArgumentList whitout auto-expansion` (maybe, in a different module)? Or, maybe, can we add documentation how to convert any `auto-expansion TypeTuple` to the `TemplateArgumentList without auto-expansion`. Thanks.
Dec 23 2013
parent reply "Dicebot" <public dicebot.lv> writes:
On Monday, 23 December 2013 at 10:15:19 UTC, ilya-stromberg wrote:
 About `auto-expansion` problem: please add documentation that
 describes difference between `auto-expansion TypeTuple` and
 `TemplateArgumentList without auto-expansion`. I personally 
 don't
 know any difference, probably because I didn't write too
 complicated meta code.
Added, does this help: http://wiki.dlang.org/DIP54#Auto-expansion_explained ?
 Also, can we keep bouth `auto-expansion TypeTuple` and
 `TemplateArgumentList whitout auto-expansion` (maybe, in a
 different module)?
Technically - yes. But I think it will cause more damage that help.
 Or, maybe, can we add documentation how to
 convert any  `auto-expansion TypeTuple` to the
 `TemplateArgumentList without auto-expansion`.
Like this? alias Packed = TemplateArgumentList!(T); // assuming T is variadic template argument list, T... alias Expanded = Packed.expand;
Dec 23 2013
parent reply "ilya-stromberg" <ilya-stromberg-2009 yandex.ru> writes:
On Monday, 23 December 2013 at 11:44:01 UTC, Dicebot wrote:
 On Monday, 23 December 2013 at 10:15:19 UTC, ilya-stromberg 
 wrote:
 About `auto-expansion` problem: please add documentation that
 describes difference between `auto-expansion TypeTuple` and
 `TemplateArgumentList without auto-expansion`. I personally 
 don't
 know any difference, probably because I didn't write too
 complicated meta code.
Added, does this help: http://wiki.dlang.org/DIP54#Auto-expansion_explained ?
Oh, I see. Thank you for the example. It really looks like `TemplateArgumentList without auto-expansion` is more generic solution. Please, add similar example to the Phobos documentation (for example, to the `http://dlang.org/tuple`) when you will implement this DIP.
 Also, can we keep bouth `auto-expansion TypeTuple` and
 `TemplateArgumentList whitout auto-expansion` (maybe, in a
 different module)?
Technically - yes. But I think it will cause more damage that help.
 Or, maybe, can we add documentation how to
 convert any  `auto-expansion TypeTuple` to the
 `TemplateArgumentList without auto-expansion`.
Like this? alias Packed = TemplateArgumentList!(T); // assuming T is variadic template argument list, T... alias Expanded = Packed.expand;
Yes, exactly. 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.
Dec 23 2013
parent reply "Dicebot" <public dicebot.lv> writes:
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.
Dec 23 2013
next sibling parent "ilya-stromberg" <ilya-stromberg-2009 yandex.ru> writes:
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.
As I understand, the main objection is that people want to see additional `auto-expansion TypeTuple` type. This alias is simple enough to explain that `.expand` and `ExpandedTemplateArgumentList` means the same. But I agree that it's not so critical to have this alias.
Dec 23 2013
prev sibling next sibling parent reply "monarch_dodra" <monarchdodra gmail.com> writes:
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. Personally, I'd prefer the name "TemplateArgumentList" be "PackedTemplateArgumentList". By doing this, the "duality" of: * ExpandedTemplateArgumentList * PackedTemplateArgumentList Will mean there will be absolutly *no* ambiguity in which is being used and how, and keep surprises to an absolute low. It keeps things explicit, and doesn't force a "default" behavior on the programmer: The programmer makes the choice all the time.
Dec 23 2013
next sibling parent reply "monarch_dodra" <monarchdodra gmail.com> writes:
 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.
Dec 23 2013
parent reply "Dicebot" <public dicebot.lv> writes:
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 :)
Dec 23 2013
parent reply "monarch_dodra" <monarchdodra gmail.com> writes:
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.
Dec 23 2013
parent reply "Dicebot" <public dicebot.lv> writes:
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.
Dec 23 2013
parent reply "monarch_dodra" <monarchdodra gmail.com> writes:
On Monday, 23 December 2013 at 14:00:21 UTC, Dicebot wrote:
 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.
My issue about this is that it will break existing code that doesn't even use the type "TypeTuple". What are the gains of: anySatisfy!(someTrait, TemplateArgumentList!(int, double)); over anySatisfy!(someTrait, int, double) Or anySatisfy!(someTrait, TemplateArgumentList!(Args)); over anySatisfy!(someTrait, Args)
 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.
No, it doesn't "replace" the language feature itself, but is replacing the *useage* itself. It's kind of like saying (hyperbole, sorry): "ref" is bad, as of now on, we use "PassByReference!" everywhere, and the caller code needs to migrate to PassByReference!, or the code won't compile anymore. But we aren't replacing the language feature "ref". YOU can still use it if YOU want to. YOU just won't be able to call any of OUR code with it... end hyperbole.
 In any case, let me re-write my question it as:

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

 This time, its legal, right?

 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
Hum... In my eyes, the "Outer" TAL gets expanded by "staticIndexOf". I'm not sure why you say "neither"?
 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 :)
Yes, actually, I think I did over complicate things. Never-mind my above point :) Still, I don't see how this: //---- template anySatisfy(alias F, T...) if (T.length == 1 && isTemplateArgumentList!(T[0])) { alias Args = T[0].expand; static if(Args.length == 0) { enum anySatisfy = false; } else static if (Args.length == 1) { enum anySatisfy = F!(Args[0]); } else { enum anySatisfy = anySatisfy!(F, isTemplateArgumentList!(Args[ 0 .. $/2])) || anySatisfy!(F, isTemplateArgumentList!(Args[$/2 .. $ ])); } } //---- Is better than: //---- template anySatisfy(alias F, T...) { static if(T.length == 0) { enum anySatisfy = false; } else static if (T.length == 1) { enum anySatisfy = F!(T[0]); } else { enum anySatisfy = anySatisfy!(F, T[ 0 .. $/2]) || anySatisfy!(F, T[$/2 .. $ ]); } } //---- I see no gains, but I see complication in both implementation and call code. The TAL just gets in *everyone's* way, with no net benefit (in this context). ---------------- Futhermore, I don't see where you'd draw the line. You proposal (this is still all about your proposal 5), wants to make std.typetuple use TAL's in all their implementations. But what about things like std.tuple.Tuple. Will that also require: Tuple!(TemplateArgumentList!(int, double, double)) myTuple? My point is that it seems (to me) that in this specific case, it is forcing the usage of a library type, where the built-in one works perfectly fine :/ I *LIKE* the idea of a PackedTemplateArgumentList, but I think it's usage should far from systematic. I'm also fine with forcing the equivalent `TypeTuple` to explicit-expand when you use, to reduce ambiguity about packaging. But the language has a built-in "Template Argument List". *That*'s what we should be using when calling them.
Dec 23 2013
next sibling parent "monarch_dodra" <monarchdodra gmail.com> writes:
On Monday, 23 December 2013 at 15:34:07 UTC, monarch_dodra wrote:
You proposal
 (this is still all about your proposal 5), wants to make 
 std.typetuple use TAL's in all their implementations.
I mean "interface".
Dec 23 2013
prev sibling parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 12/23/13 7:34 AM, monarch_dodra wrote:
 My issue about this is that it will break existing code that doesn't
 even use the type "TypeTuple". What are the gains of:

 anySatisfy!(someTrait, TemplateArgumentList!(int, double));
 over
 anySatisfy!(someTrait, int, double)

 Or

 anySatisfy!(someTrait, TemplateArgumentList!(Args));
 over
 anySatisfy!(someTrait, Args)
Dicebot, are you proposing this? It has smell. Andrei
Dec 23 2013
prev sibling parent "Dicebot" <public dicebot.lv> writes:
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.
Dec 23 2013
prev sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 12/23/13 4:25 AM, 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.
I also think that implicit expansion should not be frequent enough to justify its own abstraction. Andrei
Dec 23 2013
parent reply "deadalnix" <deadalnix gmail.com> writes:
On Monday, 23 December 2013 at 23:24:30 UTC, Andrei Alexandrescu
wrote:
 On 12/23/13 4:25 AM, 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.
I also think that implicit expansion should not be frequent enough to justify its own abstraction. Andrei
The thing is that you can build non expanding tuples on top of expanding ones, not the other way around. So I think the language should have buitin expanding tuples (and renamed something else than tuple).
Jan 16 2014
parent reply "Dicebot" <public dicebot.lv> writes:
On Thursday, 16 January 2014 at 19:15:49 UTC, deadalnix wrote:
 The thing is that you can build non expanding tuples on top of
 expanding ones, not the other way around. So I think the 
 language
 should have buitin expanding tuples (and renamed something else
 than tuple).
Wait what? template ExpandingArgList(T...) // assuming T is non-expanding { alias ExpandingArgList = T.expand; }
Jan 20 2014
parent reply "deadalnix" <deadalnix gmail.com> writes:
On Monday, 20 January 2014 at 12:36:04 UTC, Dicebot wrote:
 On Thursday, 16 January 2014 at 19:15:49 UTC, deadalnix wrote:
 The thing is that you can build non expanding tuples on top of
 expanding ones, not the other way around. So I think the 
 language
 should have buitin expanding tuples (and renamed something else
 than tuple).
Wait what? template ExpandingArgList(T...) // assuming T is non-expanding { alias ExpandingArgList = T.expand; }
The auto expand require compiler support. The non expanding behavior can be modeled on top of the auto expanding one. The problem we have goes as follow to me: - We call the expanding construct tuple, which confuse everybody. - We lack some syntactic sugar to auto expand tuples. I proposed a solution for auto unpacking random stuffs. I do think this approach is superior.
Jan 20 2014
parent "Dicebot" <public dicebot.lv> writes:
On Monday, 20 January 2014 at 20:40:30 UTC, deadalnix wrote:
 The auto expand require compiler support.
Yes. And has nothing to do with actual list behavior.
 The non expanding behavior can be modeled on top of the auto 
 expanding one.
Unfortunately not right now. Not cleanly at least. I am working on it.
 The problem we have goes as follow to me:
  - We call the expanding construct tuple, which confuse 
 everybody.
It is irrelevant topic. I think TemplateArgumentList and TemplateArgumentPack are a good names.
  - We lack some syntactic sugar to auto expand tuples. I 
 proposed a solution for auto unpacking random stuffs.
Nope. We lack lot of syntactic sugar for packs. All we have is for expanding built-in ones. Auto-unpacking and all similar extra yummies is completely orthogonal and unrelated topic I don't even want to touch.
 I do think this approach is superior.
It is simply unrelated and can be added on top of any outcome.
Jan 21 2014
prev sibling next sibling parent reply Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
On 12/23/13, Dicebot <public dicebot.lv> wrote:
 http://wiki.dlang.org/DIP54
Quoting: ---- There is also a private `std.typetuple.Pack` which is similar to current `std.typetuple.Tuple` but does not auto-expand. It is a tool absolutely necessary for more complex algorithms used in metaprogramming >>and is frequently re-invented in user libraries / projects<<. ---- If you simply remove the auto-expanding TypeTuple you will force coders to reinvent it. This may not seem like a big deal since you can simply do "alias List(T..) = T;", but it's a convenience template that should stay in Phobos. Think of it like the range primitives of arrays that are implemented in std.array. I would hate to have to re-implement empty/front/popFront/etc for arrays every time I used them if they suddenly went missing in Phobos, even if they're very trivial to implement. Especially when all of my code already depends on those functions being there. If we keep an auto-expanding TypeTuple template (but perhaps rename it), then all the user has to do to keep his code working is to do a global search & replace (transition is simple). It does still break code however. But if you remove it entirely, the user has to add his own TypeTuple template in another module, and then he has to add new import declarations in every module that used TypeTuples. That's even worse than renaming. --- Personally, I think the proper approach is: 1. Keep TypeTuple, but perhaps schedule it for renaming. 2. Introduce non-expanding equivalent to TypeTuple (in other words: make Pack public, but maybe with a different name though). 3. Add a set of documentation clearly explaining the difference between the various tuple types in Phobos and the languaage. introduces something people were reinventing in their own libraries. documentation. I have not had any problems understanding what the TypeTuple template means and how it relates to Tuple as soon as I started using both more frequently. If we have proper docs, we could even link to it from the documentation of all the tuple types in Phobos. happy **current** users, as no code will break. Maybe absolute newbies will take a while to learn the difference between these various templates, but that's what tutorials/documentation is supposed to help with. --- 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. I vote against this DIP.
Dec 23 2013
next sibling parent "Dicebot" <public dicebot.lv> writes:
On Monday, 23 December 2013 at 11:08:26 UTC, Andrej Mitrovic
wrote:
 If you simply remove the auto-expanding TypeTuple you will force
 coders to reinvent it. This may not seem like a big deal since 
 you can
 simply do "alias List(T..) = T;", but it's a convenience 
 template that
 should stay in Phobos.
This is not really true. Any instance of `TypeTuple!(a, b, c)` can be replaced with `TemplateArgumentList!(a, b, c).expand` with no additional changes or definition of custom wrappers. Such shortcut other way around is not possible - this is exactly why having single non-expanding entity can work. It does make you type more in metaprogramming code but this is relatively small inconvenience that is faster to make than to argue about. Before writing this DIP I have tested it on some of my own template-heavy code to get an impression how it may look like.
Dec 23 2013
prev sibling next sibling parent "Dicebot" <public dicebot.lv> writes:
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.
And experienced users tend to overrate value of their own habits ;) Your point would have been strong if it was some fundamental inconvenience blocking certain power use cases. However in this scenario it is just matter of litle extra typing buried deep inside generic libraries. I think I can call myself metaprogramming power user too but I am eager to to those micro extra efforts for the sake of standard library simplicity. Also while assumption that everyone will eventually become experienced user is true, not everyone will eventually be dealing with template algorithms - it is mostly business of library writers. And this newsgroup can give wrong impression about amount of library writers relatively to general user count :)
Dec 23 2013
prev sibling parent reply "JR" <zorael gmail.com> writes:
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 */ } )
Dec 23 2013
parent reply "Dicebot" <public dicebot.lv> writes:
On Monday, 23 December 2013 at 13:58:13 UTC, JR wrote:
 ... I have *almost* understood the difference between built-in 
 tuples, Tuple and TypeTuple.
I had this feeling probably 5 or 6 times in past few years, only to find some new surprise every time :D Can only hope that finally got it right in my mind now.
Dec 23 2013
parent "H. S. Teoh" <hsteoh quickfur.ath.cx> writes:
On Mon, Dec 23, 2013 at 02:04:52PM +0000, Dicebot wrote:
 On Monday, 23 December 2013 at 13:58:13 UTC, JR wrote:
... I have *almost* understood the difference between built-in
tuples, Tuple and TypeTuple.
I had this feeling probably 5 or 6 times in past few years, only to find some new surprise every time :D Can only hope that finally got it right in my mind now.
It's one of those things that the more you understand, the more you understand how much you *don't* understand. :P First there's the word "tuple" that's thrown around with multiple incompatible meanings, then you learn that "tuple" is not the same as "Tuple", and that "TypeTuple" is an alias for "tuple". Then you learn that "TypeTuple" can contain literals as well as types, contrary to its name. Then you learn about something called "parameter tuple" which *seems* to work like "tuple" aka "TypeTuple", except that it doesn't. And then ... T -- The two rules of success: 1. Don't tell everything you know. -- YHL
Dec 23 2013
prev sibling next sibling parent "ponce" <contact gam3sfrommars.fr> writes:
On Monday, 23 December 2013 at 01:39:26 UTC, Dicebot wrote:
 http://wiki.dlang.org/DIP54
Full support. Never used tuple or TypeTuple since I don't understand what they are for, and their precise relationship to templated argument lists. Better names will help. A code breakage with a compilation error is way nicer that a silent code breakage (as an example disallow the implicit conversion from static arrays to pointer broke way more code, but was safe and generally a good thing).
Dec 23 2013
prev sibling next sibling parent Michel Fortin <michel.fortin michelf.ca> writes:
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
Dec 23 2013
prev sibling next sibling parent Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
On 12/23/13, Dicebot <public dicebot.lv> wrote:
 http://wiki.dlang.org/DIP54
I'm waiting to see what others who use TypeTuples think of the DIP. E.g. Philippe Sigaud, David Nadlinger, Hara Kenji, Martin Nowak, Don Clugston, David Simcha, Steven Schveighoffer, etc. I'm pretty sure (most) of these guys use tuples a lot. Btw, is there a collection of links to the previous topics? It would be worth linking to them from the DIP.
Dec 23 2013
prev sibling next sibling parent reply "Jakob Ovrum" <jakobovrum gmail.com> writes:
I think this is just getting absurd.

The conflation between the naming issue and auto-expansion is so 
bloody dishonest. The DIP looks really good to newbies because it 
addresses the former but then they don't really understand the 
latter (as some have even said explicitly). Further, if this DIP 
had been discussed in *public* earlier, we could've handled this 
then, which could've resulted in an earlier resolution of the 
naming issue. I was genuinely wondering what was holding up the 
situation. Sigh.

The most important thing here is that std.typecons.Tuple is 
(conceptually) completely unrelated to std.typetuple.TypeTuple 
and other cases of the "tuple" name used to refer to template 
argument lists. This fact, compounded with insufficient and 
confusing documentation, causes the difficulty of learning. We 
can easily rectify this situation without any significant 
overhaul of Phobos' utility templates, which are mostly good as 
it is.

Then there is the separate issue of non-auto-expanding lists, 
necessary for algorithms that take a variadic number of variadic 
lists *that can contain types*[1]. I've been writing pretty heavy 
meta-programming code using template argument lists extensively 
since D1, and I've never required such an algorithm[2]. I've also 
taught new D programmers about template argument lists for years 
on IRC (including Dicebot), which is why I feel so strongly about 
the naming issue.

So, we're proposing that we cause this massive, non-trivial code 
breakage for the benefit of *who*, exactly? I have a feeling that 
if this is pushed through, disgruntled programmers who regard 
auto-expansion amicably will define their own substitutes for the 
previous infrastructure, which is much nicer to work with than 
the one proposed by this DIP, and much more in tune with the 
underlying language feature, *that people will still have to 
learn about*.

If a case for "packed lists" can be made, please make it 
separately.

[1] The distinction is necessary, because if only non-types are 
involved, CTFE + toTypeTuple(-ish) templates solves it, often 
very nicely.

[2] That's not to say that I think they don't exist - I know they 
do; but they are extremely niche. On the other hand, requiring a 
*fixed* number of variadic lists pops up now and then, and is 
trivially accomplished by using nested templates.
Dec 23 2013
parent reply "H. S. Teoh" <hsteoh quickfur.ath.cx> writes:
On Tue, Dec 24, 2013 at 02:52:18AM +0000, Jakob Ovrum wrote:
 I think this is just getting absurd.
 
 The conflation between the naming issue and auto-expansion is so
 bloody dishonest. The DIP looks really good to newbies because it
 addresses the former but then they don't really understand the
 latter (as some have even said explicitly). Further, if this DIP had
 been discussed in *public* earlier, we could've handled this then,
 which could've resulted in an earlier resolution of the naming
 issue. I was genuinely wondering what was holding up the situation.
 Sigh.
 
 The most important thing here is that std.typecons.Tuple is
 (conceptually) completely unrelated to std.typetuple.TypeTuple and
 other cases of the "tuple" name used to refer to template argument
 lists. This fact, compounded with insufficient and confusing
 documentation, causes the difficulty of learning. We can easily
 rectify this situation without any significant overhaul of Phobos'
 utility templates, which are mostly good as it is.
[...] So if we only implemented the first part of the DIP, the renaming of std.typeconds.TypeTuple -> std.meta.list (or whatever, let's not start bikeshedding this early), along with the documentation cleanup which is long overdue anyway, would that be more acceptable to you? As far as the auto-expand vs. non-auto-expand issue is concerned, I'm not sure why this is such a big deal. I *have* run into cases where I needed one in some cases and the other in other cases. I solved the problem by simply wrapping stuff I didn't want to auto-expand in a non-eponymous template: template SubArgs(T...) { alias expand = T; } template NeedsNestedArgs(T...) { ... // make use of T[0].expand ... // make use of T[1].expand ... // etc. } alias Instantiation = NeedsNestedArgs!( SubArgs!(...), SubArgs!(...), // will not merge with first list ... // etc. ); Unless I'm missing the elephant in the room, both the auto-expanding and non-auto-expanding template arg lists can be implemented by a 3-line template declaration each (or 1 line if you use the new parametrized alias syntax). Which anyone can (re)write in 1 minute. So why is this such a big deal? Because of standardization? If that's the issue, then the non-auto-expanding version wins, because you can always turn it into an auto-expanding list with .expand, but if you're given an auto-expanding list you have to explicitly wrap it to stop it from expanding when it shouldn't. Which requires users to reinvent their own wrappers, which defeats the purpose of standardization. Another win for non-auto-expanding is if the lists returned by std.traits.* et al are non-expanding by default, then you can pass them straight to another template as arguments without needing to worry about them flattening and merging where they aren't supposed to. Again, if you *want* to concatenate those lists, you can just use .expand (which also has the advantage of self-documenting exactly what is wanted -- the normal expectation is that separate arguments don't magically flatten out on you -- unless you're thinking of Perl lists -- so it makes sense to make expansion explicit). Going the other way requires that *every* returned list be explicitly wrapped with a custom wrapper, which seems to be putting the weight on the wrong side of the boat. Is it really *that* common to want your lists auto-expanded by default? Or am I missing something obvious here? T -- A mathematician is a device for turning coffee into theorems. -- P. Erdos
Dec 23 2013
parent reply "Jakob Ovrum" <jakobovrum gmail.com> writes:
On Tuesday, 24 December 2013 at 04:08:25 UTC, H. S. Teoh wrote:

 So if we only implemented the first part of the DIP, the 
 renaming of
 std.typeconds.TypeTuple -> std.meta.list (or whatever, let's 
 not start
 bikeshedding this early), along with the documentation cleanup 
 which is
 long overdue anyway, would that be more acceptable to you?
Yes, that's exactly what I've been arguing for since forever!
 Which requires users to reinvent their own
 wrappers, which defeats the purpose of standardization.
We should have both[1], with the auto-expanding one being the most commonly required.
 Is it really *that* common to want your lists
 auto-expanded by default?
Yes, it is. It's a natural consequence of how the language feature works. At the end of the line, after being passed around to other templates for processing (discussed below), use of template argument lists boil down to several scenarios: * Use for declaring an expression list from a type list, e.g. in a function parameter list or for fields in an aggregate. Requires expansion. * Use for initalizing other expressions lists with an expression list, e.g. passing an expression list as arguments in a function call or in an array literal. Requires expansion. * Use in static foreach. Requires expansion. * Use in special expressions that operate on types, such as `is`, `typeof` and `typeid`. Requires expansion. * Use as a public alias in a library interface, leaving the specifics of application to the user (but it always boils down to the above scenarios). Equal for both behaviours. (Some but not all of the above might be equalized by Timon Gehr's AliasThis suggestion, but this remains to be proven) Further, there is the issue of the processing itself - passing lists to algorithms receiving lists. If all of Phobos' list algorithms are rewritten to expect non-expanding lists, usage remains the same, for the *extremely* niche benefit of supporting a specific kind of variadic algorithm with the same kind of list. That's a whole lot of work for a whole lot of nothing. Hence, I think this DIP is nothing but absurd. Excuse the strong language but I'm upset that it has caused a delay in the overdue renaming issue. [1] Assuming that the case for non-auto-expanding lists can be argued sufficiently for inclusion in Phobos, which is yet to be seen. This DIP doesn't seem to even try. P.S. I too like the name `list` to replace the current `TypeTuple`. The capitalization is correct with the new Phobos rules for list algorithms, and the succinctness respects how commonly used the template is.
Dec 23 2013
parent reply "Jakob Ovrum" <jakobovrum gmail.com> writes:
On Tuesday, 24 December 2013 at 04:48:57 UTC, Jakob Ovrum wrote:
 [1] Assuming that the case for non-auto-expanding lists can be 
 argued sufficiently for inclusion in Phobos, which is yet to be 
 seen. This DIP doesn't seem to even try.
Clarification: "Assuming that the case for non-auto-expanding lists can be
 argued sufficiently for inclusion in Phobos, in the context of 
 list algorithms that take a variadic number of variadic lists 
 as arguments."
I feel that non-expanding lists only make sense in the context of these niche algorithms for the reasons explained in the parent post, and thus do not warrant conflation with auto-expanding lists.
Dec 23 2013
parent reply Dmitry Olshansky <dmitry.olsh gmail.com> writes:
24-Dec-2013 09:00, Jakob Ovrum пишет:
 On Tuesday, 24 December 2013 at 04:48:57 UTC, Jakob Ovrum wrote:
 [1] Assuming that the case for non-auto-expanding lists can be argued
 sufficiently for inclusion in Phobos, which is yet to be seen. This
 DIP doesn't seem to even try.
Clarification: "Assuming that the case for non-auto-expanding lists can be
 argued sufficiently for inclusion in Phobos, in the context of list
 algorithms that take a variadic number of variadic lists as arguments."
I feel that non-expanding lists only make sense in the context of these niche algorithms for the reasons explained in the parent post, and thus do not warrant conflation with auto-expanding lists.
As long as algorithms that operate say on 2 lists expect arguments to have '.expand' we'd be in a good shape just providing a `packList` or some such together with `list`. It would even work out of the box with current user-defined pack types if they have .expand. -- Dmitry Olshansky
Dec 24 2013
parent "Jakob Ovrum" <jakobovrum gmail.com> writes:
On Tuesday, 24 December 2013 at 10:30:47 UTC, Dmitry Olshansky 
wrote:
 As long as algorithms that operate say on 2 lists expect 
 arguments to have '.expand' we'd be in a good shape just 
 providing a `packList` or some such together with `list`.
I think so too. Of course, it is predicated on the fact that such algorithms are added to Phobos. Note that when an algorithm always expects 2 lists we can use nested templates instead, which has some benefits. The issue, of course, is that this proposal suggests having only `packList` and changing all list algorithms to expect packed lists, which I think (and have elaborated upon) is a nasty case of fighting the language for no benefit, but for serious code breakage and lots of extra code on lines that tend to be long already[1].
 It would even work out of the box with current user-defined 
 pack types if they have .expand.
Right, std.typecons.Tuple happens to be one such type. [1] It's not the case that we can simply search and replace `TypeTuple!(...)` => `TemplateArgumentList!(...).expand` and call it a day; consider code like: --- auto fun(Ranges...)(Ranges ranges) if (!is(CommonType!(staticMap!(ElementType, Ranges)) == void) { ... } --- If list algorithms are changed to receive packed list, the `Ranges` argument to `staticMap` must be changed to `TemplateArgumentList!Ranges`.
Dec 24 2013
prev sibling next sibling parent Philippe Sigaud <philippe.sigaud gmail.com> writes:
On Mon, Dec 23, 2013 at 7:34 PM, Andrej Mitrovic
<andrej.mitrovich gmail.com> wrote:
 I'm waiting to see what others who use TypeTuples think of the DIP.
 E.g. Philippe Sigaud, David Nadlinger, Hara Kenji, Martin Nowak, Don
 Clugston, David Simcha, Steven Schveighoffer, etc. I'm pretty sure
 (most) of these guys use tuples a lot.
Much as I like non-expanding tuples, I've to admit most of the standard uses of tuples (er, template argument lists) are easier if they auto-expand/flatten. I agree there are symbols that should be renamed to avoid confusion, so I agree with the renaming part. As for non-expanding, I tend to create my own (any template struct will do), but std.typecons.Tuple is perfectly serviceable. My main use is to create trees: lists are good, but there are structures that need a bit more... oomph. For example: auto myBox = computer( processor( cores(4), speed(3500.Hz), Processor.i586 ), disk( size(500.TiB) ), disk( size(750.TiB), speed(7200.rpm), Disk.SATA ), screen() ); When everything above returns a new type, possibly holding other types, and so on. The resulting type is one big tuple of tuples. I think those could be a possible way to get an internal DSL in D, at the same time statically checked by the compiler and easy to use for the programmer. So I need generic code to iterate on it, process it, modify it... But, as I said in that case, I create my own structs.
Dec 24 2013
prev sibling next sibling parent reply "Dicebot" <public dicebot.lv> writes:
Winter holidays have distracted me a bit, back to this topic.

I have been thinking about concerns mentioned for a while, this 
is proposed update to DIP in question to address those. Hope that 
will be a more acceptable compromise to everyone.

1)
Timon has raised the point that exact match between in naming 
between built-in and library type will be confusing as they will 
actually differ in behavior 
(http://forum.dlang.org/post/l99mke$q1o$1 digitalmars.com). 
Andrei has proposed `TemplateArgumentPack` as an alternative 
(http://forum.dlang.org/post/l9b5cu$2rsj$2 digitalmars.com) which 
I do like a lot.

That will also imply naming of module `std.meta.pack` instead of 
`std.meta.list`

2)
Despite my initial desire to standardize API between library 
types it seems that breakage will be much more damaging than I 
have initially expected. Jakob example 
(http://forum.dlang.org/post/vkeqyorptcobufzmmhgm forum.dlang.org) 
does not look _that_ bad but imagining is(typeof()) error 
suppression on top is pain.

I reconsider that proposal.

As an alternative, I propose signatures of existing templates 
as-is but augment them all with overloads taking single `Pack` 
(and make it requirement when introducing new ones). New 
multilist utilities added are expected to use `Pack`s (I am still 
convinced that using nested templates for that is ugly)

3)
Point about omitting expanding library type still remains. I am 
still looking for use case when those are really necessary (as a 
library type).

Does that look more acceptable? Jakob, Andrej?
Dec 29 2013
next sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 12/29/13 3:09 AM, Dicebot wrote:
 1)
 Timon has raised the point that exact match between in naming between
 built-in and library type will be confusing as they will actually differ
 in behavior (http://forum.dlang.org/post/l99mke$q1o$1 digitalmars.com).
 Andrei has proposed `TemplateArgumentPack` as an alternative
 (http://forum.dlang.org/post/l9b5cu$2rsj$2 digitalmars.com) which I do
 like a lot.

 That will also imply naming of module `std.meta.pack` instead of
 `std.meta.list`
I think a duo `TemplateArgumentList` (auto-expansion) and `TemplateArgumentPack` (no auto-expansion) in the same module is the ticket. It also makes for a wonderful opportunity to explain the distinction in the documentation and recommend idioms for each.
 As an alternative, I propose signatures of existing templates as-is but
 augment them all with overloads taking single `Pack` (and make it
 requirement when introducing new ones). New multilist utilities added
 are expected to use `Pack`s (I am still convinced that using nested
 templates for that is ugly)
To use your own argument: why add all those overloads instead of requiring the user to use .expand with a TemplateArgumentPack (or assuming we go with my suggestion above, just use a TemplateArgumentList in the first place)?
 3)
 Point about omitting expanding library type still remains. I am still
 looking for use case when those are really necessary (as a library type).
See above. I think several people argued that there are plenty of places where automatic expansion is the desired behavior. Andrei
Dec 29 2013
next sibling parent "John Colvin" <john.loughran.colvin gmail.com> writes:
On Sunday, 29 December 2013 at 15:01:03 UTC, Andrei Alexandrescu 
wrote:
 On 12/29/13 3:09 AM, Dicebot wrote:
 1)
 Timon has raised the point that exact match between in naming 
 between
 built-in and library type will be confusing as they will 
 actually differ
 in behavior 
 (http://forum.dlang.org/post/l99mke$q1o$1 digitalmars.com).
 Andrei has proposed `TemplateArgumentPack` as an alternative
 (http://forum.dlang.org/post/l9b5cu$2rsj$2 digitalmars.com) 
 which I do
 like a lot.

 That will also imply naming of module `std.meta.pack` instead 
 of
 `std.meta.list`
I think a duo `TemplateArgumentList` (auto-expansion) and `TemplateArgumentPack` (no auto-expansion) in the same module is the ticket. It also makes for a wonderful opportunity to explain the distinction in the documentation and recommend idioms for each.
This is the approach I have followed when trying to write std.meta, however I decided to split them in to two seperate modules. Then again, my module layout is a mess and I will probably rearrange considerably before submitting to the review queue. The recommended idioms drop out very neatly: `TemplateArgumentList` is for genuine variadic template arguments (where possible), `TemplateArgumentPack` is for everything else. In particular, with a (nearly)full port of std.range and std.algorithm, TemplateArgumentPacks can be used as an analogue of arrays.
Dec 29 2013
prev sibling next sibling parent "Dicebot" <public dicebot.lv> writes:
On Sunday, 29 December 2013 at 15:01:03 UTC, Andrei Alexandrescu 
wrote:
 I think a duo `TemplateArgumentList` (auto-expansion) and 
 `TemplateArgumentPack` (no auto-expansion) in the same module 
 is the ticket. It also makes for a wonderful opportunity to 
 explain the distinction in the documentation and recommend 
 idioms for each.
I am concerned about cognitive load that explanations of all those concepts at once creates. Having minimal type set allows to descend deeper iteratively. It will also be hard to explain why this type is _needed_ in stdlib (at least for me, because I have no answer for that)
 To use your own argument: why add all those overloads instead 
 of requiring the user to use .expand with a 
 TemplateArgumentPack (or assuming we go with my suggestion 
 above, just use a TemplateArgumentList in the first place)?
Signature consistency. If you will use different algorithms in same code snippet (some with single variadic argument, some with multiple) having some of arguments augmented with .expand and some not is rather ugly. I don't have strong preference here though and will be fine without adding overloads.
 3)
 Point about omitting expanding library type still remains. I 
 am still
 looking for use case when those are really necessary (as a 
 library type).
See above. I think several people argued that there are plenty of places where automatic expansion is the desired behavior.
Yep, but none of those featured auto-expanding _library_ type as part of desired behavior. May you point at specific example I have missed please?
Dec 29 2013
prev sibling parent reply "Jakob Ovrum" <jakobovrum gmail.com> writes:
On Sunday, 29 December 2013 at 15:01:03 UTC, Andrei Alexandrescu 
wrote:
 I think a duo `TemplateArgumentList` (auto-expansion) and 
 `TemplateArgumentPack` (no auto-expansion) in the same module 
 is the ticket. It also makes for a wonderful opportunity to 
 explain the distinction in the documentation and recommend 
 idioms for each.
I think we should use this chance to rectify the capitalization of the name. As the result is not exclusively a list of types, current conventions state that the name should be lowerCamelCase. I also think it should be shorter, because a) it's a fundamental, and thus very commonly used template, and b) code that manipulates lists are functional in nature which results in long lines that are also hard to split up because sometimes they are in template constraints or function template parameter lists etc. I like the name `list`.
Dec 29 2013
next sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 12/29/13 7:42 AM, Jakob Ovrum wrote:
 On Sunday, 29 December 2013 at 15:01:03 UTC, Andrei Alexandrescu wrote:
 I think a duo `TemplateArgumentList` (auto-expansion) and
 `TemplateArgumentPack` (no auto-expansion) in the same module is the
 ticket. It also makes for a wonderful opportunity to explain the
 distinction in the documentation and recommend idioms for each.
I think we should use this chance to rectify the capitalization of the name. As the result is not exclusively a list of types, current conventions state that the name should be lowerCamelCase.
Fine.
 I also think it should be shorter, because a) it's a fundamental, and
 thus very commonly used template, and b) code that manipulates lists are
 functional in nature which results in long lines that are also hard to
 split up because sometimes they are in template constraints or function
 template parameter lists etc.
No. This is the wrong place to go for short names.
 I like the name `list`.
Define your own alias that way and let the long self-explanatory be. Andrei
Dec 29 2013
next sibling parent reply "Jakob Ovrum" <jakobovrum gmail.com> writes:
On Sunday, 29 December 2013 at 16:01:41 UTC, Andrei Alexandrescu 
wrote:
 I also think it should be shorter, because a) it's a 
 fundamental, and
 thus very commonly used template, and b) code that manipulates 
 lists are
 functional in nature which results in long lines that are also 
 hard to
 split up because sometimes they are in template constraints or 
 function
 template parameter lists etc.
No. This is the wrong place to go for short names.
It would be nice to hear more than "no" when I provided two very good reasons for why I think this is the right place to go for a short name.
 I like the name `list`.
Define your own alias that way and let the long self-explanatory be.
Consistency is king; the standard name will almost always trump any other name for readability. Defaults are important :)
Dec 29 2013
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 12/29/13 8:14 AM, Jakob Ovrum wrote:
 On Sunday, 29 December 2013 at 16:01:41 UTC, Andrei Alexandrescu wrote:
 I also think it should be shorter, because a) it's a fundamental, and
 thus very commonly used template, and b) code that manipulates lists are
 functional in nature which results in long lines that are also hard to
 split up because sometimes they are in template constraints or function
 template parameter lists etc.
No. This is the wrong place to go for short names.
It would be nice to hear more than "no" when I provided two very good reasons for why I think this is the right place to go for a short name.
It's been discussed before - these are advanced notions that won't be used frequently and naively.
 I like the name `list`.
Define your own alias that way and let the long self-explanatory be.
Consistency is king; the standard name will almost always trump any other name for readability. Defaults are important :)
Yeah, on the other hand we don't want to go down in history as the language that named 'list' something that's emphatically not that. Andrei
Dec 29 2013
parent "Jakob Ovrum" <jakobovrum gmail.com> writes:
On Sunday, 29 December 2013 at 16:19:57 UTC, Andrei Alexandrescu 
wrote:
 It's been discussed before - these are advanced notions that 
 won't be used frequently and naively.
I guess I'm biased by writing a lot of library code, where it's quite frequently used. I can imagine application code using it much less.
 Yeah, on the other hand we don't want to go down in history as 
 the language that named 'list' something that's emphatically 
 not that.
That's a good point.
Dec 29 2013
prev sibling parent reply Dmitry Olshansky <dmitry.olsh gmail.com> writes:
29-Dec-2013 20:01, Andrei Alexandrescu пишет:
 On 12/29/13 7:42 AM, Jakob Ovrum wrote:
 On Sunday, 29 December 2013 at 15:01:03 UTC, Andrei Alexandrescu wrote:
 I also think it should be shorter, because a) it's a fundamental, and
 thus very commonly used template, and b) code that manipulates lists are
 functional in nature which results in long lines that are also hard to
 split up because sometimes they are in template constraints or function
 template parameter lists etc.
No. This is the wrong place to go for short names.
And having to deal with all kinds of aliases people are _expected_ to create? Why not pick something accessible in the first place? -- Dmitry Olshansky
Dec 29 2013
parent "Dicebot" <public dicebot.lv> writes:
On Sunday, 29 December 2013 at 19:02:57 UTC, Dmitry Olshansky 
wrote:
 And having to deal with all kinds of aliases people are 
 _expected_ to create? Why not pick something accessible in the 
 first place?
Because no good short name has ever been proposed so far. I'd strongly discourage creating public aliases for that in exposed code (as opposed to module/package internals) for this very reason.
Dec 29 2013
prev sibling next sibling parent reply "David Nadlinger" <code klickverbot.at> writes:
On Sunday, 29 December 2013 at 15:42:34 UTC, Jakob Ovrum wrote:
 I think we should use this chance to rectify the capitalization 
 of the name. As the result is not exclusively a list of types, 
 current conventions state that the name should be 
 lowerCamelCase.
I believe you got this one the wrong way around: Unless it is exclusively a list of values, the name should be camel cased. It is staticMap t a misnomer in that regard. David
Dec 29 2013
next sibling parent reply "Dicebot" <public dicebot.lv> writes:
On Monday, 30 December 2013 at 01:36:48 UTC, David Nadlinger 
wrote:
 On Sunday, 29 December 2013 at 15:42:34 UTC, Jakob Ovrum wrote:
 I think we should use this chance to rectify the 
 capitalization of the name. As the result is not exclusively a 
 list of types, current conventions state that the name should 
 be lowerCamelCase.
I believe you got this one the wrong way around: Unless it is exclusively a list of values, the name should be camel cased. It is staticMap t a misnomer in that regard. David
Do we actually have guidelines about casing in context of aliased content? I had impression that it is symbol on its own that matters and thus TemplateArgumentPack needs to be CamelCased simply because it is a type/template, whatever it aliases.
Dec 29 2013
parent reply "David Nadlinger" <code klickverbot.at> writes:
On Monday, 30 December 2013 at 03:01:08 UTC, Dicebot wrote:
 Do we actually have guidelines about casing in context of 
 aliased content? I had impression that it is symbol on its own 
 that matters and thus TemplateArgumentPack needs to be 
 CamelCased simply because it is a type/template, whatever it 
 aliases.
Then, all template functions would have to be camel-cased. See https://github.com/D-Programming-Language/phobos/pull/690 for a bikeshedding discussion about a related issue (expand the first "andralex commented on an outdated diff" comment stream – by the way, I still don't agree :P). David
Dec 29 2013
parent "Dicebot" <public dicebot.lv> writes:
On Monday, 30 December 2013 at 03:19:36 UTC, David Nadlinger 
wrote:
 On Monday, 30 December 2013 at 03:01:08 UTC, Dicebot wrote:
 Do we actually have guidelines about casing in context of 
 aliased content? I had impression that it is symbol on its own 
 that matters and thus TemplateArgumentPack needs to be 
 CamelCased simply because it is a type/template, whatever it 
 aliases.
Then, all template functions would have to be camel-cased. See https://github.com/D-Programming-Language/phobos/pull/690 for a bikeshedding discussion about a related issue (expand the first "andralex commented on an outdated diff" comment stream – by the way, I still don't agree :P). David
Thanks for educating, good to know this rule :)
Dec 29 2013
prev sibling parent "Jakob Ovrum" <jakobovrum gmail.com> writes:
On Monday, 30 December 2013 at 01:36:48 UTC, David Nadlinger 
wrote:
 On Sunday, 29 December 2013 at 15:42:34 UTC, Jakob Ovrum wrote:
 I think we should use this chance to rectify the 
 capitalization of the name. As the result is not exclusively a 
 list of types, current conventions state that the name should 
 be lowerCamelCase.
I believe you got this one the wrong way around: Unless it is exclusively a list of values, the name should be camel cased. It is staticMap t a misnomer in that regard. David
I'm fine with any convention as long as we have one.
Dec 30 2013
prev sibling parent "David Nadlinger" <code klickverbot.at> writes:
On Sunday, 29 December 2013 at 15:42:34 UTC, Jakob Ovrum wrote:
 I think we should use this chance to rectify the capitalization 
 of the name. As the result is not exclusively a list of types, 
 current conventions state that the name should be 
 lowerCamelCase.
I believe you got this one the wrong way around: Unless it is exclusively a list of values, the name should be camel cased. It is staticMap that is the misnomer in this regard. David
Dec 29 2013
prev sibling parent reply "Jakob Ovrum" <jakobovrum gmail.com> writes:
On Sunday, 29 December 2013 at 11:10:00 UTC, Dicebot wrote:
 Despite my initial desire to standardize API between library 
 types it seems that breakage will be much more damaging than I 
 have initially expected. Jakob example 
 (http://forum.dlang.org/post/vkeqyorptcobufzmmhgm forum.dlang.org) 
 does not look _that_ bad but imagining is(typeof()) error 
 suppression on top is pain.
Breakage that causes errors in secondary locations and cannot be automatically repaired (e.g. search & replace) is the worst kind of breakage, after silent failures, that I can think of.
 As an alternative, I propose signatures of existing templates 
 as-is but augment them all with overloads taking single `Pack` 
 (and make it requirement when introducing new ones).
Not a single of the existing algorithms need packed lists. Further, this DIP doesn't present a single algorithm that *does* need packed lists. It adds a huge maintenance cost and cognitive cost for no benefit.
 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.
 Point about omitting expanding library type still remains. I am 
 still looking for use case when those are really necessary (as 
 a library type).
As elaborated upon in an earlier post[1], I think auto-expansion is *the* use case for template argument lists, as a natural consequence of language features. That's what makes this DIP so absurd - you are asking everyone to type `.expand` literally everywhere such a list is actually applied. The only tangible rationale for this was that auto-expansion is hard to learn, which I think is not only unsubstantiated, but rather moot because I think *expansion* is what needs grokking, and there's no way around that because at the end of the line, expansion is the only use case of template argument lists. By fixing the naming issue, we'd be making strides in easing teaching of list expansion, without making lists harder to use by sometimes requiring `.expand` and sometimes not, sometimes requiring `TemplateArgumentPack!Args` and sometimes just `Args`, and without breaking code in non-trivial ways. [1] http://forum.dlang.org/post/glqrqbynhpeidktrbjca forum.dlang.org
Dec 29 2013
next sibling parent reply "Dicebot" <public dicebot.lv> writes:
On Sunday, 29 December 2013 at 15:35:50 UTC, Jakob Ovrum wrote:
 ...
Sorry, can you make a short summary about your position? You are against adding packed list to library or just against removing expanding one (from the library)?
Dec 29 2013
parent "Jakob Ovrum" <jakobovrum gmail.com> writes:
On Sunday, 29 December 2013 at 15:45:59 UTC, Dicebot wrote:
 On Sunday, 29 December 2013 at 15:35:50 UTC, Jakob Ovrum wrote:
 ...
Sorry, can you make a short summary about your position? You are against adding packed list to library or just against removing expanding one (from the library)?
Packed lists are a niche, which necessity isn't well argued by this DIP, so I suggest we postpone assessment of packed lists until their utility is proven. (Personally I suspect their utility will prove plenty worthy of Phobos) Auto-expanding lists cover the vast majority of use cases, so we shouldn't conflate them with packed lists because this comes at various costs.
Dec 29 2013
prev sibling parent reply "Dicebot" <public dicebot.lv> writes:
Back to fighting :)

On Sunday, 29 December 2013 at 15:35:50 UTC, Jakob Ovrum wrote:
 Breakage that causes errors in secondary locations and cannot 
 be automatically repaired (e.g. search & replace) is the worst 
 kind of breakage, after silent failures, that I can think of.
This is why I have considered this a serious objection and changed my mind on that topic. Or have I still missed some possible breakage of that kind&
 As an alternative, I propose signatures of existing templates 
 as-is but augment them all with overloads taking single `Pack` 
 (and make it requirement when introducing new ones).
Not a single of the existing algorithms need packed lists. Further, this DIP doesn't present a single algorithm that *does* need packed lists. It adds a huge maintenance cost and cognitive cost for no benefit.
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? 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. 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".
 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"
 Point about omitting expanding library type still remains. I 
 am still looking for use case when those are really necessary 
 (as a library type).
As elaborated upon in an earlier post[1], I think auto-expansion is *the* use case for template argument lists,
I'll copy list from there: "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) "Use for initalizing other expressions lists with an expression list" - should require expansion anyway because it is how std.typecons.Tuple works "Use in static foreach" - works with alias this "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". "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 Only thing I have difficulties with right now is defining static opSlice for Pack so that it may return another Pack instead of raw list. But that looks like compiler defect and should work as far as I read the spec. I will work on DMD PR if this is going to be accepted as "the way".
 as a natural consequence of language features. That's what 
 makes this DIP so absurd - you are asking everyone to type 
 `.expand` literally everywhere such a list is actually applied.
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. 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.
 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.
 By fixing the naming issue, we'd be making strides in easing 
 teaching of list expansion, without making lists harder to use 
 by sometimes requiring `.expand` and sometimes not, sometimes 
 requiring `TemplateArgumentPack!Args` and sometimes just 
 `Args`, and without breaking code in non-trivial ways.
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.
Dec 29 2013
next sibling parent reply Timon Gehr <timon.gehr gmx.ch> writes:
On 12/29/2013 10:41 PM, Dicebot wrote:
...
 "Use in static foreach" - works with alias this

 "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".
 ...
What would be an example of code that you consider to be broken? (TemplateArgumentList!(int, double) is a valid type and TemplateArgumentList!(1, 2.0) is a value of that type.)
 ...

 Only thing I have difficulties with right now is defining static opSlice
 for Pack so that it may return another Pack instead of raw list. But
 that looks like compiler defect and should work as far as I read the
 spec.
This problem is also present in std.typecons.Tuple. Where does the spec claim that static opSlice can work for this use case? I find the fact that alias this is required for implementation of either Tuple or Pack to be an annoying language limitation.
 I will work on DMD PR if this is going to be accepted as "the way".
I think this will require another DIP.
Dec 29 2013
parent reply "Dicebot" <public dicebot.lv> writes:
On Monday, 30 December 2013 at 00:20:43 UTC, Timon Gehr wrote:
 What would be an example of code that you consider to be broken?
 (TemplateArgumentList!(int, double) is a valid type and 
 TemplateArgumentList!(1, 2.0) is a value of that type.)
Stuff that relies that, for example, that `is(TypeTuple!(int, double) == typeof(TypeTuple!(42, 2.0)))`. There is no place in specification that defines / guarantees it or even define tuple as a valid type entity (or, to be precise, I have been looking for one and failed to find the mention). It behaves as if one is the instance of the other but is more of coincidence than intended rule. I also remember Andrei mentioning in one of tuple threads that this relation is not supposed to be valid in general but it is very hard to find exact comment right now. Andrei can you please either confirm this or call me wrong? :)
 Only thing I have difficulties with right now is defining 
 static opSlice
 for Pack so that it may return another Pack instead of raw 
 list. But
 that looks like compiler defect and should work as far as I 
 read the
 spec.
This problem is also present in std.typecons.Tuple. Where does the spec claim that static opSlice can work for this use case?
It is in line with general rule of opXXX for structs working as syntax rewrite. Spec needs to claim it is not legal in that regard, not other way around ;) But for this to be helpful it needs to turn indexes into template arguments and this will be enhancement request for sure.
 I find the fact that alias this is required for implementation 
 of either Tuple or Pack to be an annoying language limitation.
Me too. Maybe it should be addressed in general by defining template-argument opXXX - than it is subject of own DIP indeed. It is not critical for this DIP implementation so I did not think about it in details but it can make implementation much more hygienic.
Dec 29 2013
next sibling parent reply Timon Gehr <timon.gehr gmx.ch> writes:
On 12/30/2013 03:58 AM, Dicebot wrote:
 On Monday, 30 December 2013 at 00:20:43 UTC, Timon Gehr wrote:
 What would be an example of code that you consider to be broken?
 (TemplateArgumentList!(int, double) is a valid type and
 TemplateArgumentList!(1, 2.0) is a value of that type.)
Stuff that relies that, for example, that `is(TypeTuple!(int, double) == typeof(TypeTuple!(42, 2.0)))`. There is no place in specification that defines / guarantees it or even define tuple as a valid type entity (or, to be precise, I have been looking for one and failed to find the mention).
The spec is poor here, but it _still_ implies that the type of an 'expression tuple' is the corresponding 'type tuple'. http://dlang.org/tuple.html In any case, if something is to be fixed here it is the spec. It seems not formal enough if there can be any doubt that this is not intended behaviour. (Many language features are specified by example rather than by general rules.)
 It behaves as if one is the instance of the other but is more
 of coincidence than intended rule.
 ...
I'm sorry, but this is nonsense. The list of type / type of list confusion is not a rule that gets accidentally implemented in a compiler.
 I also remember Andrei mentioning in one of tuple threads that this
 relation is not supposed to be valid in general
Unlikely. Andrei is considered a D expert.
 but it is very hard to
 find exact comment right now. Andrei can you please either confirm this
 or call me wrong? :)

 Only thing I have difficulties with right now is defining static opSlice
 for Pack so that it may return another Pack instead of raw list. But
 that looks like compiler defect and should work as far as I read the
 spec.
This problem is also present in std.typecons.Tuple. Where does the spec claim that static opSlice can work for this use case?
It is in line with general rule of opXXX for structs working as syntax rewrite.
No, it is not.
 Spec needs to claim it is not legal in that regard, not other
 way around ;)
???
 But for this to be helpful it needs to turn indexes into
 template arguments and this will be enhancement request for sure.
 ...
This.
 I find the fact that alias this is required for implementation of
 either Tuple or Pack to be an annoying language limitation.
Me too. Maybe it should be addressed in general by defining template-argument opXXX - than it is subject of own DIP indeed. It is not critical for this DIP implementation so I did not think about it in details but it can make implementation much more hygienic.
It's critical if you want to support the real opSlice.
Dec 29 2013
parent reply "Dicebot" <public dicebot.lv> writes:
On Monday, 30 December 2013 at 03:37:56 UTC, Timon Gehr wrote:
 It is in line with general rule of opXXX for structs working 
 as syntax
 rewrite.
No, it is not.
"No" as in "not in line" or "you interpret rules wrong"?
 Me too. Maybe it should be addressed in general by defining
 template-argument opXXX - than it is subject of own DIP 
 indeed. It is
 not critical for this DIP implementation so I did not think 
 about it in
 details but it can make implementation much more hygienic.
It's critical if you want to support the real opSlice.
What do you mean by "real"? Naive alias this implementation will be sliceable. Problem is without this feature it will degenerate into raw argument list upon slicing which is not clean but not fatal (still an improvement over existing TypeTuple)
Dec 29 2013
parent reply Timon Gehr <timon.gehr gmx.ch> writes:
On 12/30/2013 05:08 AM, Dicebot wrote:
 On Monday, 30 December 2013 at 03:37:56 UTC, Timon Gehr wrote:
 It is in line with general rule of opXXX for structs working as syntax
 rewrite.
No, it is not.
"No" as in "not in line" or "you interpret rules wrong"? ...
Both. There is no precedent for rewriting operator arguments to template value arguments neither in the spec, in newsgroup discussions on the design of a potential feature, nor in the implementation. You seemed to claim this is merely a compiler bug and this can be deduced from the spec by analogy, so you also appear to interpret rules wrong.
 Me too. Maybe it should be addressed in general by defining
 template-argument opXXX - than it is subject of own DIP indeed. It is
 not critical for this DIP implementation so I did not think about it in
 details but it can make implementation much more hygienic.
It's critical if you want to support the real opSlice.
What do you mean by "real"?
The one that actually gives you a Pack back.
 Naive alias this implementation will be
 sliceable. Problem is without this feature it will degenerate into raw
 argument list upon slicing which is not clean but not fatal (still an
 improvement over existing TypeTuple)
Questionable. Slicing is a common operation.
Dec 29 2013
parent reply "Dicebot" <public dicebot.lv> writes:
On Monday, 30 December 2013 at 04:35:04 UTC, Timon Gehr wrote:
 Both. There is no precedent for rewriting operator arguments to 
 template value arguments neither in the spec, in newsgroup 
 discussions on the design of a potential feature, nor in the 
 implementation. You seemed to claim this is merely a compiler 
 bug and this can be deduced from the spec by analogy, so you 
 also appear to interpret rules wrong.
Ah I was referring to the fact that it does not seem to compile even assuming normal non-template parameters as indexes (which looks like a bug). Other part (which is real desired one) is not allowed by spec right now indeed. struct X { static int opSlice(size_t a, size_t b) { return 42; } } static assert ( X[1..2] == 42 ); // Error: cannot slice type 'X' I expected this one to work.
 Naive alias this implementation will be
 sliceable. Problem is without this feature it will degenerate 
 into raw
 argument list upon slicing which is not clean but not fatal 
 (still an
 improvement over existing TypeTuple)
Questionable. Slicing is a common operation
Sure and I am going to try it. But it is not a showstopper for DIP in question I think.
Dec 29 2013
next sibling parent Timon Gehr <timon.gehr gmx.ch> writes:
On 12/30/2013 05:55 AM, Dicebot wrote:
 Ah I was referring to the fact that it does not seem to compile even
 assuming normal non-template parameters as indexes (which looks like a
 bug). Other part (which is real desired one) is not allowed by spec
 right now indeed.

 struct X
 {
      static int opSlice(size_t a, size_t b)
      {
          return 42;
      }
 }

 static assert ( X[1..2] == 42 );

 // Error: cannot slice type 'X'

 I expected this one to work.
Ah, I see.
Dec 29 2013
prev sibling parent reply "Meta" <jared771 gmail.com> writes:
On Monday, 30 December 2013 at 04:55:41 UTC, Dicebot wrote:
 Ah I was referring to the fact that it does not seem to compile 
 even assuming normal non-template parameters as indexes (which 
 looks like a bug). Other part (which is real desired one) is 
 not allowed by spec right now indeed.

 struct X
 {
 	static int opSlice(size_t a, size_t b)
 	{
 		return 42;
 	}
 }

 static assert ( X[1..2] == 42 );

 // Error: cannot slice type 'X'

 I expected this one to work.

 Naive alias this implementation will be
 sliceable. Problem is without this feature it will degenerate 
 into raw
 argument list upon slicing which is not clean but not fatal 
 (still an
 improvement over existing TypeTuple)
Questionable. Slicing is a common operation
Sure and I am going to try it. But it is not a showstopper for DIP in question I think.
This almost looks like something that could work, but is explicitly disallowed by the compiler. struct Test { enum opSlice(size_t a, size_t b) = 42; } //Error: can only slice tuple types, not Test Test[1..2] t2;
Dec 29 2013
parent "Meta" <jared771 gmail.com> writes:
On Monday, 30 December 2013 at 06:48:11 UTC, Meta wrote:
 This almost looks like something that could work, but is 
 explicitly disallowed by the compiler.

 	struct Test
 	{
 		enum opSlice(size_t a, size_t b) = 42;
 	}
 	
 	//Error: can only slice tuple types, not Test
 	Test[1..2] t2;
Actually, no, nevermind. I got ahead of myself. It's probably just a canned message.
Dec 29 2013
prev sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 12/29/13 6:58 PM, Dicebot wrote:
 On Monday, 30 December 2013 at 00:20:43 UTC, Timon Gehr wrote:
 What would be an example of code that you consider to be broken?
 (TemplateArgumentList!(int, double) is a valid type and
 TemplateArgumentList!(1, 2.0) is a value of that type.)
Stuff that relies that, for example, that `is(TypeTuple!(int, double) == typeof(TypeTuple!(42, 2.0)))`. There is no place in specification that defines / guarantees it or even define tuple as a valid type entity (or, to be precise, I have been looking for one and failed to find the mention). It behaves as if one is the instance of the other but is more of coincidence than intended rule. I also remember Andrei mentioning in one of tuple threads that this relation is not supposed to be valid in general but it is very hard to find exact comment right now. Andrei can you please either confirm this or call me wrong? :)
I don't understand the question. I think there's no particular relation between TemplateArgument{List,Pack}!(int, double) and TemplateArgument{List,Pack}!(1, 2.0). One is a list of two types and the other is a list of two values, and yah, if you map typeof over the arguments in the latter it so happens you get the types in the first. Template arguments lists are what they are - entities that can be passed to templates. Aliasing them is sensible but creating values thereof does not make sense. Tuples are a different beast altogether. It would be nice to be able to extract their support types as a TemplateArgument{List,Pack} but that's about it. One more word about providing TemplateArgument{List,Pack} vs. only one of them. Our users fall into categories such as: 0. Language lawyers who've studied the fine distinctions and are able to use either abstraction and define what they need if missing. 1. Experts who have an understanding of what they need and expect, and may or may not be surprised by whichever behavior we choose. 2. Users who have only a vague idea what the power is, and would have a difficult time using self-expansion when not needed or vice versa. 3. Users who don't know the first thing about the entire notion of grouping template arguments together. I think we'd harm one or more categories of these users if we choose for them. We can't win. Conversely, we'd inform and please them all if we attacked the matter head on with a combination of TemplateArgument{List,Pack} and their afferent documentation. Andrei
Dec 29 2013
next sibling parent reply "Dicebot" <public dicebot.lv> writes:
On Monday, 30 December 2013 at 03:44:49 UTC, Andrei Alexandrescu 
wrote:
 I don't understand the question. I think there's no particular 
 relation between TemplateArgument{List,Pack}!(int, double) and 
 TemplateArgument{List,Pack}!(1, 2.0). One is a list of two 
 types and the other is a list of two values, and yah, if you 
 map typeof over the arguments in the latter it so happens you 
 get the types in the first.
See example in that post. Right now you can apply typeof to template argument list despite it not being a first class type and get list of types of its elements. It also only place in language where it allows to apply typeof on type: is(typeof(TypeTuple!(42, int)) == TypeTuple!(int, int)) It gets worse when you consider so called expression lists: TypeTuple!(int, double) vals; This looks like instance of type list but it is in fact works (afaik) effectively as: int _tmp1; int _tmp2; alias vals = TypeTuple!(_tmp1, _tmp2); It is yet another special case that makes template argument list act as first class type despite not being one. As you may have notice confusion is so high that Timon did not even believe me remembering your quote about no particular relation between those two :)
 One more word about providing TemplateArgument{List,Pack} vs. 
 only one of them. Our users fall into categories such as:

 0. Language lawyers who've studied the fine distinctions and 
 are able to use either abstraction and define what they need if 
 missing.

 1. Experts who have an understanding of what they need and 
 expect, and may or may not be surprised by whichever behavior 
 we choose.

 2. Users who have only a vague idea what the power is, and 
 would have a difficult time using self-expansion when not 
 needed or vice versa.

 3. Users who don't know the first thing about the entire notion 
 of grouping template arguments together.

 I think we'd harm one or more categories of these users if we 
 choose for them. We can't win. Conversely, we'd inform and 
 please them all if we attacked the matter head on with a 
 combination of TemplateArgument{List,Pack} and their afferent 
 documentation.
If it is you judgement, let it be so. I prefer to start working on implementation whatever it is as opposed to endless discussion. What is your opinion about defining general guideline to use packs over nested templates for multi-list algorithms (another disagreement between me and Jakob)?
Dec 29 2013
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 12/29/13 8:03 PM, Dicebot wrote:
 It is yet another special case that makes template argument list act as
 first class type despite not being one.
Oh, I see. Yah, that's odd but then such is life. I think it's a tolerable special case.
 If it is you judgement, let it be so. I prefer to start working on
 implementation whatever it is as opposed to endless discussion. What is
 your opinion about defining general guideline to use packs over nested
 templates for multi-list algorithms (another disagreement between me and
 Jakob)?
I think an argument advocating a bunch of changes that add chaff to code that works very well would have a hard time geting off the ground. Use the right tool for the job - that's why we're providing two of them. Andrei
Dec 29 2013
parent reply "Dicebot" <public dicebot.lv> writes:
On Monday, 30 December 2013 at 06:42:56 UTC, Andrei Alexandrescu 
wrote:
 If it is you judgement, let it be so. I prefer to start 
 working on
 implementation whatever it is as opposed to endless 
 discussion. What is
 your opinion about defining general guideline to use packs 
 over nested
 templates for multi-list algorithms (another disagreement 
 between me and
 Jakob)?
I think an argument advocating a bunch of changes that add chaff to code that works very well would have a hard time geting off the ground. Use the right tool for the job - that's why we're providing two of them.
It is not related to any existing code as there are no multi-list templates in std.typetuple right now. What I am speaking about is defining new ones in two possible ways: template Equals(T1...) { template To(T2...) { ... } } vs template Equals(alias T1, alias T2) if (isTemplateArgumentPack!T1 && isTemplateArgumentPack!T2) { } I think default Phobos style should be the latter while Jakob seems to favor the former. Judgement of uninterested party is welcome.
Dec 30 2013
next sibling parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 12/30/13 12:39 AM, Dicebot wrote:
 On Monday, 30 December 2013 at 06:42:56 UTC, Andrei Alexandrescu wrote:
 If it is you judgement, let it be so. I prefer to start working on
 implementation whatever it is as opposed to endless discussion. What is
 your opinion about defining general guideline to use packs over nested
 templates for multi-list algorithms (another disagreement between me and
 Jakob)?
I think an argument advocating a bunch of changes that add chaff to code that works very well would have a hard time geting off the ground. Use the right tool for the job - that's why we're providing two of them.
It is not related to any existing code as there are no multi-list templates in std.typetuple right now. What I am speaking about is defining new ones in two possible ways: template Equals(T1...) { template To(T2...) { ... } } vs template Equals(alias T1, alias T2) if (isTemplateArgumentPack!T1 && isTemplateArgumentPack!T2) { } I think default Phobos style should be the latter while Jakob seems to favor the former. Judgement of uninterested party is welcome.
I think the latter style is more natural. Andrei
Dec 30 2013
prev sibling parent "John Colvin" <john.loughran.colvin gmail.com> writes:
On Monday, 30 December 2013 at 08:39:55 UTC, Dicebot wrote:
 On Monday, 30 December 2013 at 06:42:56 UTC, Andrei 
 Alexandrescu wrote:
 If it is you judgement, let it be so. I prefer to start 
 working on
 implementation whatever it is as opposed to endless 
 discussion. What is
 your opinion about defining general guideline to use packs 
 over nested
 templates for multi-list algorithms (another disagreement 
 between me and
 Jakob)?
I think an argument advocating a bunch of changes that add chaff to code that works very well would have a hard time geting off the ground. Use the right tool for the job - that's why we're providing two of them.
It is not related to any existing code as there are no multi-list templates in std.typetuple right now. What I am speaking about is defining new ones in two possible ways: template Equals(T1...) { template To(T2...) { ... } } vs template Equals(alias T1, alias T2) if (isTemplateArgumentPack!T1 && isTemplateArgumentPack!T2) { } I think default Phobos style should be the latter while Jakob seems to favor the former. Judgement of uninterested party is welcome.
The latter is the style I went for. However, with TemplateArgumentPack as a struct, the alias' aren't necessary. It's just a type :)
Dec 30 2013
prev sibling next sibling parent reply Timon Gehr <timon.gehr gmx.ch> writes:
On 12/30/2013 04:44 AM, Andrei Alexandrescu wrote:
 I don't understand the question. I think there's no particular relation
 between TemplateArgument{List,Pack}!(int, double) and
 TemplateArgument{List,Pack}!(1, 2.0). One is a list of two types and the
 other is a list of two values, and yah, if you map typeof over the
 arguments in the latter it so happens you get the types in the first.

 Template arguments lists are what they are - entities that can be passed
 to templates. Aliasing them is sensible but creating values thereof does
 not make sense.
You are doing it in the implementation of std.typecons.Tuple, and on every variadic function template call. How does it not make sense?
Dec 29 2013
next sibling parent reply "Dicebot" <public dicebot.lv> writes:
On Monday, 30 December 2013 at 04:07:42 UTC, Timon Gehr wrote:
 Template arguments lists are what they are - entities that can 
 be passed
 to templates. Aliasing them is sensible but creating values 
 thereof does
 not make sense.
You are doing it in the implementation of std.typecons.Tuple, and on every variadic function template call. How does it not make sense?
See my clarification here - http://forum.dlang.org/post/msumrnieryzifgcyuiqc forum.dlang.org It is not creation of instance in general language meaning, it is special case implemented specifically for template argument lists which just happen to look so naturally close to instantiation. In fact it creates new template argument lists of aliases to variables, one can do the same trick manually with named variables with exactly same effect.
Dec 29 2013
parent reply Timon Gehr <timon.gehr gmx.ch> writes:
On 12/30/2013 05:11 AM, Dicebot wrote:
 On Monday, 30 December 2013 at 04:07:42 UTC, Timon Gehr wrote:
 Template arguments lists are what they are - entities that can be passed
 to templates. Aliasing them is sensible but creating values thereof does
 not make sense.
You are doing it in the implementation of std.typecons.Tuple, and on every variadic function template call. How does it not make sense?
See my clarification here - http://forum.dlang.org/post/msumrnieryzifgcyuiqc forum.dlang.org It is not creation of instance in general language meaning, it is special case implemented specifically for template argument lists which just happen to look so naturally close to instantiation. In fact it creates new template argument lists of aliases to variables, one can do the same trick manually with named variables with exactly same effect.
Just to get your assumption that I am confused out of the way, I am fully aware how this is most easily implemented (in fact, I _have_ implemented it in my own partly-finished D programming language frontend.) If you are going to claim that this is not proper creation of an instance of a type, except that: int x; static assert(is(typeof(x)==int)); Seq!(int, double) y; static assert(is(typeof(y)==Seq!(int, double))); // presumably "bad" Then I don't know what to tell you. It is not useful at all to make a terminological distinction between the two cases above and claim that one is somehow special and confusing, when everything actually behaves in an uniform way.
Dec 29 2013
next sibling parent reply "Dicebot" <public dicebot.lv> writes:
On Monday, 30 December 2013 at 04:25:22 UTC, Timon Gehr wrote:
 If you are going to claim that this is not proper creation of 
 an instance of a type, except that:

 int x;
 static assert(is(typeof(x)==int));

 Seq!(int, double) y;
 static assert(is(typeof(y)==Seq!(int, double))); // presumably 
 "bad"

 Then I don't know what to tell you. It is not useful at all to 
 make a terminological distinction between the two cases above 
 and claim that one is somehow special and confusing, when 
 everything actually behaves in an uniform way.
Same as type list is not type but list of types, expression list is not an instance but list of aliases to instances. This is important distinction terminology-wise at least and pretty much the reason this thing has no ABI which is huge semantical thing on its own. I'd love it to be designed and implemented in such way (I have even posted such proposal in past) but it is not the case for both DMD and spec right now. I am not an expert in DMD internals so I am taking Don's word on this (we have been talking on this topic some time ago in person).
Dec 29 2013
parent Timon Gehr <timon.gehr gmx.ch> writes:
On 12/30/2013 05:51 AM, Dicebot wrote:
 On Monday, 30 December 2013 at 04:25:22 UTC, Timon Gehr wrote:
 If you are going to claim that this is not proper creation of an
 instance of a type, except that:

 int x;
 static assert(is(typeof(x)==int));

 Seq!(int, double) y;
 static assert(is(typeof(y)==Seq!(int, double))); // presumably "bad"

 Then I don't know what to tell you. It is not useful at all to make a
 terminological distinction between the two cases above and claim that
 one is somehow special and confusing, when everything actually behaves
 in an uniform way.
Same as type list is not type but list of types,
Both.
 expression list is not an instance but list of aliases to instances.
Both.
 This is important distinction terminology-wise at least
I don't think the terms are mutually exclusive. D eliminates the distinction.
 and pretty much the reason this thing has no ABI which is huge semantical
thing on its own.
 ...
The reason it has no ABI is that it cannot be returned from functions. (Which the spec mentions as a TODO and I support as a non-standard extension.)
 I'd love it to be designed and implemented in such way (I have even
 posted such proposal in past) but it is not the case for both DMD and
 spec right now. I am not an expert in DMD internals so I am taking Don's
 word on this (we have been talking on this topic some time ago in person).
I think both the spec and the external behaviour of DMD support the viewpoint that type lists are also types.
Dec 29 2013
prev sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 12/29/13 8:25 PM, Timon Gehr wrote:
 On 12/30/2013 05:11 AM, Dicebot wrote:
 On Monday, 30 December 2013 at 04:07:42 UTC, Timon Gehr wrote:
 Template arguments lists are what they are - entities that can be
 passed
 to templates. Aliasing them is sensible but creating values thereof
 does
 not make sense.
You are doing it in the implementation of std.typecons.Tuple, and on every variadic function template call. How does it not make sense?
See my clarification here - http://forum.dlang.org/post/msumrnieryzifgcyuiqc forum.dlang.org It is not creation of instance in general language meaning, it is special case implemented specifically for template argument lists which just happen to look so naturally close to instantiation. In fact it creates new template argument lists of aliases to variables, one can do the same trick manually with named variables with exactly same effect.
Just to get your assumption that I am confused out of the way, I am fully aware how this is most easily implemented (in fact, I _have_ implemented it in my own partly-finished D programming language frontend.) If you are going to claim that this is not proper creation of an instance of a type, except that: int x; static assert(is(typeof(x)==int)); Seq!(int, double) y; static assert(is(typeof(y)==Seq!(int, double))); // presumably "bad" Then I don't know what to tell you. It is not useful at all to make a terminological distinction between the two cases above and claim that one is somehow special and confusing, when everything actually behaves in an uniform way.
The latter holds no state though. Andrei
Dec 29 2013
parent reply Timon Gehr <timon.gehr gmx.ch> writes:
On 12/30/2013 07:45 AM, Andrei Alexandrescu wrote:
 ...
 If you are going to claim that this is not proper creation of an
 instance of a type, except that:

 int x;
 static assert(is(typeof(x)==int));

 Seq!(int, double) y;
 static assert(is(typeof(y)==Seq!(int, double))); // presumably "bad"

 Then I don't know what to tell you. It is not useful at all to make a
 terminological distinction between the two cases above and claim that
 one is somehow special and confusing, when everything actually behaves
 in an uniform way.
The latter holds no state though. Andrei
alias Seq(T...)=T; void main(){ Seq!(int, double) y; y=Seq!(1,2.0); assert(y==Seq!(1,2.0)); y[0]=2; assert(y==Seq!(2,2.0)); y=Seq!(3,4.0); assert(y==Seq!(3,4.0)); int x; }
Dec 30 2013
parent Timon Gehr <timon.gehr gmx.ch> writes:
On 12/30/2013 07:26 PM, Timon Gehr wrote:
      assert(y==Seq!(3,4.0)); int x;
(Ignore the 'x' :o).)
Dec 30 2013
prev sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 12/29/13 8:07 PM, Timon Gehr wrote:
 On 12/30/2013 04:44 AM, Andrei Alexandrescu wrote:
 I don't understand the question. I think there's no particular relation
 between TemplateArgument{List,Pack}!(int, double) and
 TemplateArgument{List,Pack}!(1, 2.0). One is a list of two types and the
 other is a list of two values, and yah, if you map typeof over the
 arguments in the latter it so happens you get the types in the first.

 Template arguments lists are what they are - entities that can be passed
 to templates. Aliasing them is sensible but creating values thereof does
 not make sense.
You are doing it in the implementation of std.typecons.Tuple, and on every variadic function template call. How does it not make sense?
This is a misunderstanding. I don't know how to clear it. Andrei
Dec 29 2013
parent reply Timon Gehr <timon.gehr gmx.ch> writes:
On 12/30/2013 07:43 AM, Andrei Alexandrescu wrote:
 Template arguments lists are what they are - entities that can be passed
 to templates. Aliasing them is sensible but creating values thereof does
 not make sense.
You are doing it in the implementation of std.typecons.Tuple, and on every variadic function template call. How does it not make sense?
This is a misunderstanding.
I guess this is a matter of exposition rather than understanding.
 I don't know how to clear it.
Usually, by communication.
Dec 30 2013
parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 12/30/13 10:31 AM, Timon Gehr wrote:
 On 12/30/2013 07:43 AM, Andrei Alexandrescu wrote:
 Template arguments lists are what they are - entities that can be
 passed
 to templates. Aliasing them is sensible but creating values thereof
 does
 not make sense.
You are doing it in the implementation of std.typecons.Tuple, and on every variadic function template call. How does it not make sense?
This is a misunderstanding.
I guess this is a matter of exposition rather than understanding.
Yah, I was the one who misunderstood. Andrei
Dec 30 2013
prev sibling parent "Jakob Ovrum" <jakobovrum gmail.com> writes:
On Monday, 30 December 2013 at 03:44:49 UTC, Andrei Alexandrescu 
wrote:
 Template arguments lists are what they are - entities that can 
 be passed to templates. Aliasing them is sensible but creating 
 values thereof does not make sense.
That's very confusing. Declaring an expression list from a type list is the most common use of template argument lists in the first place: void write(Args...)(Args args) { ... }
 Tuples are a different beast altogether. It would be nice to be 
 able to extract their support types as a 
 TemplateArgument{List,Pack} but that's about it.
Hopefully/ideally tuples have nothing to do with all this, otherwise we're back to square one with the naming issue.
Dec 30 2013
prev sibling parent "Jakob Ovrum" <jakobovrum gmail.com> writes:
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.
Dec 30 2013
prev sibling next sibling parent "Dicebot" <public dicebot.lv> writes:
On Monday, 23 December 2013 at 01:39:26 UTC, Dicebot wrote:
 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.
Short update - I am going to try to implement PR for dmd which will allow template argument opSlice & friends (and thus hygienic packed typed), will return to this topic once it is figured out.
Jan 01 2014
prev sibling next sibling parent "Dicebot" <public dicebot.lv> writes:
On Monday, 23 December 2013 at 01:39:26 UTC, Dicebot wrote:
 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.
Small update on this. I have chosen to go route of investigating compiler enhancement possibilities first to allow cleaner argument pack implementation. After some tweaks it was relatively easy to make work these two samples: ----- struct X { static int opSlice(size_t l, size_t u) { return l + u; } } pragma(msg, X[1..2]); ----- and ----- struct X { // note the template args static auto opSlice(size_t l, size_t u)() { return l + u; } } pragma(msg, X[1..2]); ----- However I am still struggling with more practical example: ----- struct X(T...) { static auto opSlice(size_t l, size_t u)() { return X!(T[l..u]); } } alias Y = (X!(1, 2, 3))[1..2]; ----- It seems to take completely different processing path, one that does not allow obvious syntax rewriting before semantic pass. I think I'll throw few more weeks into trying this and proceed with crappy alternative upon failure.
Jan 16 2014
prev sibling parent reply "Dicebot" <public dicebot.lv> writes:
Have updated the DIP to include feedback from this thread : 
http://wiki.dlang.org/DIP54

It effectively means resorting back to both std.meta.pack and 
std.meta.list as a compromise.

Unfortunately I was not able to hack compiler into doing opSlice 
overloading desired for hygienic TemplateArgumentPack 
implementation. opSlice itself is doable but I have a big problem 
with existing opDollar implementation which effectively replaces 
$ with a reference to local variable __dollar__ making it 
impossible to use one in contexts where no hidden variable can be 
injected. Restructuring frontend to use different opDollar 
semantics is beyond my current knowledge and I want to move 
forward with it.

Hope to start working on it soon. Ironically, getting a D job has 
stripped me of almost all time spent on side D tasks so progress 
is very slow, sorry :(
Mar 07 2014
parent reply "Jakob Ovrum" <jakobovrum gmail.com> writes:
On Friday, 7 March 2014 at 19:06:27 UTC, Dicebot wrote:
 Have updated the DIP to include feedback from this thread : 
 http://wiki.dlang.org/DIP54

 It effectively means resorting back to both std.meta.pack and 
 std.meta.list as a compromise.
LGTM.
 Hope to start working on it soon. Ironically, getting a D job 
 has stripped me of almost all time spent on side D tasks so 
 progress is very slow, sorry :(
Perhaps you can delegate some tasks to other members of the community. I vaguely remember other members working on similar modules to std.meta.*, too (John Colvin?). Personally I would be happy to help with the task of rewriting dlang.org/tuple and other documentation. Since the name of the page itself is problematic, I suggest we introduce a new page with the migrated and rewritten tuple.dd information (named what, though? I think it should cover both lists and packs), then leaving tuple.dd as a small stub that succinctly explains the terminology change as well as linking to the new page, std.typecons.Tuple/std.tuple and probably to DIP54, too.
Mar 14 2014
next sibling parent reply "John Colvin" <john.loughran.colvin gmail.com> writes:
On Friday, 14 March 2014 at 09:55:34 UTC, Jakob Ovrum wrote:
 On Friday, 7 March 2014 at 19:06:27 UTC, Dicebot wrote:
 Have updated the DIP to include feedback from this thread : 
 http://wiki.dlang.org/DIP54

 It effectively means resorting back to both std.meta.pack and 
 std.meta.list as a compromise.
LGTM.
 Hope to start working on it soon. Ironically, getting a D job 
 has stripped me of almost all time spent on side D tasks so 
 progress is very slow, sorry :(
Perhaps you can delegate some tasks to other members of the community. I vaguely remember other members working on similar modules to std.meta.*, too (John Colvin?).
Yes, I am using an almost identical layout to what is proposed in this DIP. The bulk of the work is done, but tests are thin on the ground. I have a whole bunch of changes that haven't been commited and pushed to github yet. I should be able to bring everything up to date over the weekend. Also, I noticed I haven't attributed some work I stole from other peoples pull requests, so I'll fix that too. There are a few enhancements to the language that would make a big difference, as well as some bugs that are holding me back. In particular, if there was such a thing as "symbol opDispatch" that provided an alias to the symbol used after the . instead of a string, UFCS for templates would be workable without horrible leaky abstractions.
Mar 14 2014
parent reply "Dicebot" <public dicebot.lv> writes:
On Friday, 14 March 2014 at 11:01:15 UTC, John Colvin wrote:
 On Friday, 14 March 2014 at 09:55:34 UTC, Jakob Ovrum wrote:
 On Friday, 7 March 2014 at 19:06:27 UTC, Dicebot wrote:
 Have updated the DIP to include feedback from this thread : 
 http://wiki.dlang.org/DIP54

 It effectively means resorting back to both std.meta.pack and 
 std.meta.list as a compromise.
LGTM.
 Hope to start working on it soon. Ironically, getting a D job 
 has stripped me of almost all time spent on side D tasks so 
 progress is very slow, sorry :(
Perhaps you can delegate some tasks to other members of the community. I vaguely remember other members working on similar modules to std.meta.*, too (John Colvin?).
Yes, I am using an almost identical layout to what is proposed in this DIP. The bulk of the work is done, but tests are thin on the ground. I have a whole bunch of changes that haven't been commited and pushed to github yet. I should be able to bring everything up to date over the weekend. Also, I noticed I haven't attributed some work I stole from other peoples pull requests, so I'll fix that too.
By the way, can you separate your work in 2 parts - one that exactly mirrors existing std.typetuple functionality and second one with any additions? We shouldn't process those under single review process.
 There are a few enhancements to the language that would make a 
 big difference, as well as some bugs that are holding me back.
Can you list those? (with a high priority for those that impact "base" proposal) For me main issue is lack of symbol-based opSlice / opIndex but as I have already mentioned fixing it is a bit over my current DMD knowledge.
 In particular, if there was such a thing as "symbol opDispatch" 
 that provided an alias to the symbol used after the . instead 
 of a string, UFCS for templates would be workable without 
 horrible leaky abstractions.
I don't think it is a good feature, it probably can't even be done within existing language semantics. Probably your problem can be solved via other means?
Mar 14 2014
parent "John Colvin" <john.loughran.colvin gmail.com> writes:
On Friday, 14 March 2014 at 13:32:34 UTC, Dicebot wrote:
 On Friday, 14 March 2014 at 11:01:15 UTC, John Colvin wrote:
 On Friday, 14 March 2014 at 09:55:34 UTC, Jakob Ovrum wrote:
 On Friday, 7 March 2014 at 19:06:27 UTC, Dicebot wrote:
 Have updated the DIP to include feedback from this thread : 
 http://wiki.dlang.org/DIP54

 It effectively means resorting back to both std.meta.pack 
 and std.meta.list as a compromise.
LGTM.
 Hope to start working on it soon. Ironically, getting a D 
 job has stripped me of almost all time spent on side D tasks 
 so progress is very slow, sorry :(
Perhaps you can delegate some tasks to other members of the community. I vaguely remember other members working on similar modules to std.meta.*, too (John Colvin?).
Yes, I am using an almost identical layout to what is proposed in this DIP. The bulk of the work is done, but tests are thin on the ground. I have a whole bunch of changes that haven't been commited and pushed to github yet. I should be able to bring everything up to date over the weekend. Also, I noticed I haven't attributed some work I stole from other peoples pull requests, so I'll fix that too.
By the way, can you separate your work in 2 parts - one that exactly mirrors existing std.typetuple functionality and second one with any additions? We shouldn't process those under single review process.
Sure.
 There are a few enhancements to the language that would make a 
 big difference, as well as some bugs that are holding me back.
Can you list those? (with a high priority for those that impact "base" proposal)
I'll take a look over the weekend.
 For me main issue is lack of symbol-based opSlice / opIndex but 
 as I have already mentioned fixing it is a bit over my current 
 DMD knowledge.

 In particular, if there was such a thing as "symbol 
 opDispatch" that provided an alias to the symbol used after 
 the . instead of a string, UFCS for templates would be 
 workable without horrible leaky abstractions.
I don't think it is a good feature, it probably can't even be done within existing language semantics. Probably your problem can be solved via other means?
It's very nice to be able to write like this: enum integerStorageLength = TL.Map!isIntegral.Filter!isTrue.length; (admittedly that example would easily done other ways) It can already work completely seemlessly for templates internal to std.meta, or indeed for module-global public templates from anywhere. It's only for local/private/protected symbols from outside that a "symbol opDispatch" is needed.
Mar 14 2014
prev sibling parent "Dicebot" <public dicebot.lv> writes:
On Friday, 14 March 2014 at 09:55:34 UTC, Jakob Ovrum wrote:
 Hope to start working on it soon. Ironically, getting a D job 
 has stripped me of almost all time spent on side D tasks so 
 progress is very slow, sorry :(
Perhaps you can delegate some tasks to other members of the community. I vaguely remember other members working on similar modules to std.meta.*, too (John Colvin?). Personally I would be happy to help with the task of rewriting dlang.org/tuple and other documentation. Since the name of the page itself is problematic, I suggest we introduce a new page with the migrated and rewritten tuple.dd information (named what, though? I think it should cover both lists and packs), then leaving tuple.dd as a small stub that succinctly explains the terminology change as well as linking to the new page, std.typecons.Tuple/std.tuple and probably to DIP54, too.
Code itself is not a big problem (thanks to John work), it is documentation that bothers me. Both terrible with writing docs and have only basic knowledge of DDOC. If someone can help with it, it will definitely speed up things.
Mar 14 2014