www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - DIP63 : operator overloading for raw templates

reply "Dicebot" <public dicebot.lv> writes:
http://wiki.dlang.org/DIP63

This is solution for a problem I am currently having with 
implementing http://wiki.dlang.org/DIP54 (afair it was also 
mentioned by Timon Gehr during old discussion of that DIP)

New proposed semantics ( to catch your attention and get to read 
the link ;) ):

template Pack(T...)
{
     alias expand = T;

     alias opIndex(size_t index) = T[index];
     alias opSlice(size_t lower, size_t upper) = 
Pack!(T[lower..upper]);
     alias opDollar = T.length;
}

// no ambiguity as Pack!(int, int) is not a valid type
// is(element == int)
alias element = Pack!(int, int)[1];
Jun 15 2014
next sibling parent Timon Gehr <timon.gehr gmx.ch> writes:
On 06/15/2014 08:32 PM, Dicebot wrote:
 http://wiki.dlang.org/DIP63

 This is solution for a problem I am currently having with implementing
 http://wiki.dlang.org/DIP54 (afair it was also mentioned by Timon Gehr
 during old discussion of that DIP)

 New proposed semantics ( to catch your attention and get to read the
 link ;) ):

 template Pack(T...)
 {
      alias expand = T;

      alias opIndex(size_t index) = T[index];
      alias opSlice(size_t lower, size_t upper) = Pack!(T[lower..upper]);
      alias opDollar = T.length;
 }

 // no ambiguity as Pack!(int, int) is not a valid type
 // is(element == int)
 alias element = Pack!(int, int)[1];

LGTM. Maybe you can add something along the following lines as another motivating use case: struct Tuple(T...){ T expand; template Pack(){ auto opSlice(size_t lower, size_t upper){ return tuple(expand[lower..upper]); } } alias Pack!() this; } auto tuple(T...)(T args){ return Tuple!T(args); } void main(){ Tuple!(double,int,string) t1=tuple(1.0,2,"three"); auto t2=t1[1..$]; static assert(is(typeof(t2)==Tuple!(int,string))); foreach(i,v;t1) writeln(i,": ",v); } I.e. this solution is general enough to fix the "unhygienic" behaviour of Phobos tuple slicing.
Jun 15 2014
prev sibling next sibling parent "Marc =?UTF-8?B?U2Now7x0eiI=?= <schuetzm gmx.net> writes:
On Sunday, 15 June 2014 at 18:32:31 UTC, Dicebot wrote:
 http://wiki.dlang.org/DIP63

 This is solution for a problem I am currently having with 
 implementing http://wiki.dlang.org/DIP54 (afair it was also 
 mentioned by Timon Gehr during old discussion of that DIP)

 New proposed semantics ( to catch your attention and get to 
 read the link ;) ):

 template Pack(T...)
 {
     alias expand = T;

     alias opIndex(size_t index) = T[index];
     alias opSlice(size_t lower, size_t upper) = 
 Pack!(T[lower..upper]);
     alias opDollar = T.length;
 }

 // no ambiguity as Pack!(int, int) is not a valid type
 // is(element == int)
 alias element = Pack!(int, int)[1];

I guess there's no way around it, but it seems inconsistent that the operators are defined as templated aliases instead of functions as anywhere else. Could you add a paragraph to the DIP which points this out and give a short justification?
Jun 16 2014
prev sibling next sibling parent "matovitch" <camille.brugel laposte.net> writes:
On Monday, 16 June 2014 at 08:56:24 UTC, Marc Schütz wrote:
 On Sunday, 15 June 2014 at 18:32:31 UTC, Dicebot wrote:
 http://wiki.dlang.org/DIP63

 This is solution for a problem I am currently having with 
 implementing http://wiki.dlang.org/DIP54 (afair it was also 
 mentioned by Timon Gehr during old discussion of that DIP)

 New proposed semantics ( to catch your attention and get to 
 read the link ;) ):

 template Pack(T...)
 {
    alias expand = T;

    alias opIndex(size_t index) = T[index];
    alias opSlice(size_t lower, size_t upper) = 
 Pack!(T[lower..upper]);
    alias opDollar = T.length;
 }

 // no ambiguity as Pack!(int, int) is not a valid type
 // is(element == int)
 alias element = Pack!(int, int)[1];

I guess there's no way around it, but it seems inconsistent that the operators are defined as templated aliases instead of functions as anywhere else. Could you add a paragraph to the DIP which points this out and give a short justification?

+1 And why these operators only ? struct StaticVariant { alias opAssign(T t) = (immutable T x = t; alias x this;) } struct Json { immutable (StaticVariant[string]); alias opDispatch(string s, T t) = (data[s] ~= t); alias opDispatch(string s) = data[s]; } void main() { Json john; john.size = 1.78; john.name = "John"; float johnSize = john.size; string johnName = john.name; } Ok I am a dreaming D beginner. In this case multiple alias this would be better. Also, I don't understand why we can't append immutable array thanks to CTFE too. D is awesome in lots of ways but it's quite frustrating too because it frees your imagination. Where do we set the limit in terms of meta-meta-stuff ?
Jun 16 2014
prev sibling next sibling parent "matovitch" <camille.brugel laposte.net> writes:
Well I realized I was a bit off-topic there since it is not about
ctfe operators but raw template operators. I'm out.
Jun 16 2014
prev sibling next sibling parent "Dicebot" <public dicebot.lv> writes:
On Monday, 16 June 2014 at 08:56:24 UTC, Marc Schütz wrote:
 I guess there's no way around it, but it seems inconsistent 
 that the operators are defined as templated aliases instead of 
 functions as anywhere else. Could you add a paragraph to the 
 DIP which points this out and give a short justification?

Updated with QA. Q: It seems inconsistent that the operators are defined as templated aliases instead of functions as anywhere else. A: To be able to mimic semantics of template argument lists such overloaded operators need to be able to return types and symbols which is not possible with function. However, planned implementation should accept functions too, as well as anything that fits `Symbol.opSlice!(a, b)` call pattern.
Jun 16 2014
prev sibling next sibling parent "Dicebot" <public dicebot.lv> writes:
On Monday, 16 June 2014 at 12:37:55 UTC, matovitch wrote:
 And why these operators only ?

tl; dr: because I am limiting proposal to what I am actually able and willing to implement :)
Jun 16 2014
prev sibling next sibling parent "deadalnix" <deadalnix gmail.com> writes:
On Sunday, 15 June 2014 at 18:32:31 UTC, Dicebot wrote:
 http://wiki.dlang.org/DIP63

 This is solution for a problem I am currently having with 
 implementing http://wiki.dlang.org/DIP54 (afair it was also 
 mentioned by Timon Gehr during old discussion of that DIP)

 New proposed semantics ( to catch your attention and get to 
 read the link ;) ):

 template Pack(T...)
 {
     alias expand = T;

     alias opIndex(size_t index) = T[index];
     alias opSlice(size_t lower, size_t upper) = 
 Pack!(T[lower..upper]);
     alias opDollar = T.length;
 }

 // no ambiguity as Pack!(int, int) is not a valid type
 // is(element == int)
 alias element = Pack!(int, int)[1];

I have nothing against it BUT... The fact that you need this is a proof that TemplateArgumentList/TemplateArgumentPack have actually use outside being template argument list and/or pack. Your just defeated you whole Q/A on DIP54...
Jun 16 2014
prev sibling next sibling parent "deadalnix" <deadalnix gmail.com> writes:
On Tuesday, 17 June 2014 at 00:26:56 UTC, deadalnix wrote:
 I have nothing against it BUT...

 The fact that you need this is a proof that 
 TemplateArgumentList/TemplateArgumentPack have actually use 
 outside being template argument list and/or pack.

 Your just defeated you whole Q/A on DIP54...

To be more constructive, naming something by its use will fatally look very weird and confusing when other uses are found. And here we see that it is not even implemented but already have other uses. Can we please avoid that pitfall ? Either name is sequence (it was popular in previous discussions) or group or something. Anything.
Jun 16 2014
prev sibling next sibling parent "Dicebot" <public dicebot.lv> writes:
On Tuesday, 17 June 2014 at 00:26:56 UTC, deadalnix wrote:
 I have nothing against it BUT...

 The fact that you need this is a proof that 
 TemplateArgumentList/TemplateArgumentPack have actually use 
 outside being template argument list and/or pack.

 Your just defeated you whole Q/A on DIP54...

Hm, have I ever said those are never used? x_X Quite the contrary, good chunk of discussion was about how this is foundation for implementing majority of std.meta I still can do it without DIP63 (this is for example what vibe.d internal meta package uses) but I can't get myself into placing something like this in standard library, it feels too Boost. DIP63 does not change anything fundamentally about DIP54 but allows much more readable and maintainable implementation.
Jun 16 2014
prev sibling next sibling parent "Dicebot" <public dicebot.lv> writes:
On Tuesday, 17 June 2014 at 00:36:43 UTC, deadalnix wrote:
 To be more constructive, naming something by its use will 
 fatally look very weird and confusing when other uses are 
 found. And here we see that it is not even implemented but 
 already have other uses. Can we please avoid that pitfall ?

It is not named by its use. I have never meant that. Template argument list is what that thing _is_, by definition and compiler implementation. We simply don't have any other construct in the language to refer to with no semantic confusion.
Jun 16 2014
prev sibling parent "Dicebot" <public dicebot.lv> writes:
Added some basic implementation 
(https://github.com/D-Programming-Language/dmd/pull/3758), need 
some feedback from any DMD hackers who actually know how stuff is 
supposed to work :(
Jul 13 2014