www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - template syntax

reply dronord <dronord gmail.com> writes:
Hello!

Thanks for best language syntax! But templates.

Templates are traditional is {} or <>.

!(exclamation mark) sense/perceive as stop symbol, by my mean.

< and > is nice construction. May be add it in D?)

Again, big thanks for language!
Jan 30 2019
next sibling parent reply Neia Neutuladh <neia ikeran.org> writes:
On Wed, 30 Jan 2019 19:17:38 +0000, dronord wrote:
 Templates are traditional is {} or <>.
I've never seen {} for templates. I believe I've only seen [], <>, (), and !().
 < and > is nice construction. May be add it in D?)
D is a mature language, and part of that is not making changes without a good reason. There is a good reason *not* to use <>: it's ambiguous. Consider: A<B> C; This can be parsed as: alias SomeType = A<B>; SomeType C; or: bool aLessThanB = A < B; aLessThanB > C; Similarly, the expression: Func(A<B, C>(1)); could either be: auto tmp1 = A < B; auto tmp2 = C > (1); Func(tmp1, tmp2); or: alias SomeFunc = A<B, C>; Func(SomeFunc(1)); It's generally considered bad if you have to defer parsing until you have semantic data available. D didn't manage to eliminate the lexer hack, unfortunately.
Jan 30 2019
next sibling parent reply Dennis <dkorpel gmail.com> writes:
On Wednesday, 30 January 2019 at 19:42:06 UTC, Neia Neutuladh 
wrote:
 D didn't manage to eliminate the lexer hack, unfortunately.
Huh, I thought it did since casts use a keyword and pointer-type declarations always supercede multiplication. Where does it fail?
Jan 30 2019
parent Neia Neutuladh <neia ikeran.org> writes:
On Wed, 30 Jan 2019 20:13:28 +0000, Dennis wrote:
 On Wednesday, 30 January 2019 at 19:42:06 UTC, Neia Neutuladh wrote:
 D didn't manage to eliminate the lexer hack, unfortunately.
Huh, I thought it did since casts use a keyword and pointer-type declarations always supercede multiplication. Where does it fail?
Whoops, my mistake, it *does* fix the lexer hack.
Jan 30 2019
prev sibling next sibling parent Walter Bright <newshound2 digitalmars.com> writes:
On 1/30/2019 11:42 AM, Neia Neutuladh wrote:
 D didn't manage to eliminate the lexer hack, unfortunately.
??
Jan 30 2019
prev sibling parent reply bpr <brogoff gmail.com> writes:
On Wednesday, 30 January 2019 at 19:42:06 UTC, Neia Neutuladh 
wrote:
 On Wed, 30 Jan 2019 19:17:38 +0000, dronord wrote:
 Templates are traditional is {} or <>.
I've never seen {} for templates. I believe I've only seen [], <>, (), and !().
Julia uses the curly brackets for type parameterization.
 < and > is nice construction. May be add it in D?)
D is a mature language, and part of that is not making changes without a good reason.
I much prefer the D template syntax even though I'm way more used to '<>' from C++, Java, and Rust. If I were going to make a change in syntax to D3 I'd make variable declaration syntax postfix, like Go, Scala, Kotlin, Rust...
Feb 03 2019
parent reply bauss <jj_1337 live.dk> writes:
On Sunday, 3 February 2019 at 19:37:57 UTC, bpr wrote:
 I much prefer the D template syntax even though I'm way more 
 used to '<>' from C++, Java, and Rust. If I were going to make 
 a change in syntax to D3 I'd make variable declaration syntax 
 postfix, like Go, Scala, Kotlin, Rust...
I hope that does not happen. I absolutely hate it.
Feb 03 2019
parent Jonathan Marler <johnnymarler gmail.com> writes:
On Monday, 4 February 2019 at 07:19:32 UTC, bauss wrote:
 On Sunday, 3 February 2019 at 19:37:57 UTC, bpr wrote:
 I much prefer the D template syntax even though I'm way more 
 used to '<>' from C++, Java, and Rust. If I were going to make 
 a change in syntax to D3 I'd make variable declaration syntax 
 postfix, like Go, Scala, Kotlin, Rust...
I hope that does not happen. I absolutely hate it.
Tell us more. I've thought about this one but haven't been able to determine if either method is objectively better. How do you think each method would affect a language in general?
Feb 04 2019
prev sibling next sibling parent reply "H. S. Teoh" <hsteoh quickfur.ath.cx> writes:
On Wed, Jan 30, 2019 at 07:17:38PM +0000, dronord via Digitalmars-d wrote:
[...]
 Templates are traditional is {} or <>.
 
 !(exclamation mark) sense/perceive as stop symbol, by my mean.
 
 < and > is nice construction. May be add it in D?)
[...] The choice of ! for template instantiation may perhaps be challenged, but seriously, < and > for templates??! That's one of the absolutely worst design choices C++ has ever made, which has made C++ infamous for being unlexable until it's parsed, not to mention produced utterly horrific unreadable template syntax. Take for example this D snippet: auto myFunc(alias less, Args...)(Args args) { ... } myFunc!((a, b) => a < b)(...); Try writing the second line with C++'s < and > syntax, and you get the monstrosity: myFunc<(a, b) => a < b>(...); The real fun begins with nested templates: myFunc<nested<(a, b) => xform<(x, y) < z>(a) > xform<(x, y) < z>(b)>>(...); Now your <'s and >'s have become unreadably ambiguous and virtually impossible to parse. With !, it may not look so pretty, but at least it's not ambiguous: myFunc!(nested!((a, b) => xform!((x, y) < z)(a) > xform!((x, y) < z)(b)))(...); Please, let's leave C++'s < > mistake in the dustbins of history. Such suffering ought not be inflicted upon our future generations. T -- "Hi." "'Lo."
Jan 30 2019
next sibling parent reply Patrick Schluter <Patrick.Schluter bbox.fr> writes:
On Wednesday, 30 January 2019 at 20:12:13 UTC, H. S. Teoh wrote:
 On Wed, Jan 30, 2019 at 07:17:38PM +0000, dronord via 
 Digitalmars-d wrote: [...]
 The real fun begins with nested templates:

 	myFunc<nested<(a, b) => xform<(x, y) < z>(a) > xform<(x, y) < 
 z>(b)>>(...);
I hope you didn't forget the space between the >'s. Or else it might shift some value somewhere :-)
Jan 30 2019
next sibling parent reply "H. S. Teoh" <hsteoh quickfur.ath.cx> writes:
On Wed, Jan 30, 2019 at 08:51:24PM +0000, Patrick Schluter via Digitalmars-d
wrote:
 On Wednesday, 30 January 2019 at 20:12:13 UTC, H. S. Teoh wrote:
 On Wed, Jan 30, 2019 at 07:17:38PM +0000, dronord via Digitalmars-d
 wrote: [...]
 The real fun begins with nested templates:
 
 	myFunc<nested<(a, b) => xform<(x, y) < z>(a) > xform<(x, y) <
 z>(b)>>(...);
 
I hope you didn't forget the space between the >'s. Or else it might shift some value somewhere :-)
Recent versions of C++ ostensibly have "solved" that problem, so that no intervening space is needed anymore. Of course, that doesn't really solve the problem; it only introduces more complexity in the parser / lexer, and in all likelihood more pathological corner cases to come back and bite you when you least expect it. (Just like, sorry to say, many of C++'s other recent additions that try to patch over legacy design flaws, but end up making things worse in other ways.) Like, if certain symbols are defined differently, the >> could actually become a bit-shift operator. And with free-for-all operator overloading, who knows *what* that would actually mean semantically. Here's another example of why < and > ambiguity is so evil: take this innocent-looking expression: myFunc<T, U>(a, b); Since C++ allows you to overload the comma operator, myFunc could be an object that overloads operator<(), and myFunc<T returns an object that then combines via operator,() with U to produce another object that is then compared via > with the result of another comma operator overload that returns a third object for (a, b). I.e., the above line could actually be parsed as: ((myFunc < T) , U) > (a, b); in spite of looking like calling a template function. Don't you just love C++??! T -- Almost all proofs have bugs, but almost all theorems are true. -- Paul Pedersen
Jan 30 2019
parent reply Walter Bright <newshound2 digitalmars.com> writes:
On 1/30/2019 1:28 PM, H. S. Teoh wrote:
 Recent versions of C++ ostensibly have "solved" that problem, so that no
 intervening space is needed anymore.
I implemented the lexer hack back in the 90's, but had to back it out to get it through the C++98 test suite. Then, I had to add it back in to match later C++ Standards :-)
 Of course, that doesn't really solve the problem; it only introduces
 more complexity in the parser / lexer, and in all likelihood more
 pathological corner cases to come back and bite you when you least
 expect it.
I think the .template syntax is to work around such a corner case.
Jan 30 2019
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 1/30/19 4:57 PM, Walter Bright wrote:
 On 1/30/2019 1:28 PM, H. S. Teoh wrote:
 Recent versions of C++ ostensibly have "solved" that problem, so that no
 intervening space is needed anymore.
I implemented the lexer hack back in the 90's, but had to back it out to get it through the C++98 test suite. Then, I had to add it back in to match later C++ Standards :-)
 Of course, that doesn't really solve the problem; it only introduces
 more complexity in the parser / lexer, and in all likelihood more
 pathological corner cases to come back and bite you when you least
 expect it.
I think the .template syntax is to work around such a corner case.
Don't forget "typename" and "::template", beautifully combined here: typedef typename Allocator::template rebind<Mapped>::other mapped_type_allocator; Andrei
Jan 30 2019
parent reply Walter Bright <newshound2 digitalmars.com> writes:
On 1/30/2019 4:08 PM, Andrei Alexandrescu wrote:
 Don't forget "typename" and "::template", beautifully combined here:
 
 typedef typename Allocator::template rebind<Mapped>::other
mapped_type_allocator;
It is indeed beautiful. Want to write a DIP to switch to < > ?
Jan 30 2019
next sibling parent reply "H. S. Teoh" <hsteoh quickfur.ath.cx> writes:
On Wed, Jan 30, 2019 at 05:11:07PM -0800, Walter Bright via Digitalmars-d wrote:
 On 1/30/2019 4:08 PM, Andrei Alexandrescu wrote:
 Don't forget "typename" and "::template", beautifully combined here:
 
 typedef typename Allocator::template rebind<Mapped>::other
mapped_type_allocator;
It is indeed beautiful. Want to write a DIP to switch to < > ?
I second! And while we're at it, how about reinstating the comma operator and introducing opComma, and additionally opLess, opLessEqual, opGreater, opGreaterEqual, opNotEqual, and opDot? It will be greatly helpful with a library implementation of < > syntax, which will be an important step to gauge how useful it will be in practice, and could in the meantime serve as a good substitute in lieu of a complicated in-compiler implementation. T -- Making non-nullable pointers is just plugging one hole in a cheese grater. -- Walter Bright
Jan 30 2019
next sibling parent bauss <jj_1337 live.dk> writes:
On Thursday, 31 January 2019 at 01:28:29 UTC, H. S. Teoh wrote:
 And while we're at it, how about reinstating the comma operator 
 and introducing opComma, and additionally opLess, opLessEqual, 
 opGreater, opGreaterEqual, opNotEqual, and opDot?  It will be 
 greatly helpful with a library implementation of < > syntax, 
 which will be an important step to gauge how useful it will be 
 in practice, and could in the meantime serve as a good 
 substitute in lieu of a complicated in-compiler implementation.


 T
Also an opAnd
Jan 31 2019
prev sibling parent reply Seb <seb wilzba.ch> writes:
On Thursday, 31 January 2019 at 01:28:29 UTC, H. S. Teoh wrote:
 On Wed, Jan 30, 2019 at 05:11:07PM -0800, Walter Bright via 
 Digitalmars-d wrote:
 On 1/30/2019 4:08 PM, Andrei Alexandrescu wrote:
 Don't forget "typename" and "::template", beautifully 
 combined here:
 
 typedef typename Allocator::template rebind<Mapped>::other 
 mapped_type_allocator;
It is indeed beautiful. Want to write a DIP to switch to < > ?
I second! And while we're at it, how about reinstating the comma operator and introducing opComma, and additionally opLess, opLessEqual, opGreater, opGreaterEqual, opNotEqual, and opDot? It will be greatly helpful with a library implementation of < > syntax, which will be an important step to gauge how useful it will be in practice, and could in the meantime serve as a good substitute in lieu of a complicated in-compiler implementation. T
FWIW opDot still exists in DMD as of 2.084.0 (and nightly): https://github.com/dlang/dmd/blob/2457038c1ac37fbe1098b4b3d98007761149dfaf/test/runnable/xtest46.d#L130 It's just deprecated. We don't have opGreater/opEqual, but there's still opAnd: https://github.com/dlang/dmd/blob/06d3770d3baf51ce0b4b9998bf6a4e0369ee8f02/test/runnable/opover.d In fact all these old D1 operator overloads (opPos,opNeg,..., opShl, opShr,..., opMul_r) are still supported in DMD and don't even trigger a deprecation message: https://github.com/dlang/dmd/blob/06d3770d3baf51ce0b4b9998bf6a4e0369ee8f02/src/dmd/id.d#L206
Jan 31 2019
parent bauss <jj_1337 live.dk> writes:
On Thursday, 31 January 2019 at 13:01:09 UTC, Seb wrote:
 On Thursday, 31 January 2019 at 01:28:29 UTC, H. S. Teoh wrote:
 On Wed, Jan 30, 2019 at 05:11:07PM -0800, Walter Bright via 
 Digitalmars-d wrote:
 On 1/30/2019 4:08 PM, Andrei Alexandrescu wrote:
 Don't forget "typename" and "::template", beautifully 
 combined here:
 
 typedef typename Allocator::template rebind<Mapped>::other 
 mapped_type_allocator;
It is indeed beautiful. Want to write a DIP to switch to < > ?
I second! And while we're at it, how about reinstating the comma operator and introducing opComma, and additionally opLess, opLessEqual, opGreater, opGreaterEqual, opNotEqual, and opDot? It will be greatly helpful with a library implementation of <
 syntax, which will be an important step to gauge how useful
it will be in practice, and could in the meantime serve as a good substitute in lieu of a complicated in-compiler implementation. T
FWIW opDot still exists in DMD as of 2.084.0 (and nightly): https://github.com/dlang/dmd/blob/2457038c1ac37fbe1098b4b3d98007761149dfaf/test/runnable/xtest46.d#L130 It's just deprecated. We don't have opGreater/opEqual, but there's still opAnd: https://github.com/dlang/dmd/blob/06d3770d3baf51ce0b4b9998bf6a4e0369ee8f02/test/runnable/opover.d In fact all these old D1 operator overloads (opPos,opNeg,..., opShl, opShr,..., opMul_r) are still supported in DMD and don't even trigger a deprecation message: https://github.com/dlang/dmd/blob/06d3770d3baf51ce0b4b9998bf6a4e0369ee8f02/src/dmd/id.d#L206
Someone needs to do some cleanup.
Jan 31 2019
prev sibling parent reply Arun Chandrasekaran <aruncxy gmail.com> writes:
On Wed, Jan 30, 2019 at 5:15 PM Walter Bright via Digitalmars-d
<digitalmars-d puremagic.com> wrote:
 On 1/30/2019 4:08 PM, Andrei Alexandrescu wrote:
 Don't forget "typename" and "::template", beautifully combined here:

 typedef typename Allocator::template rebind<Mapped>::other
mapped_type_allocator;
It is indeed beautiful. Want to write a DIP to switch to < > ?
Bauss will win another worst code contest if this DIP gets approved ;-)
Jan 30 2019
parent reply bauss <jj_1337 live.dk> writes:
On Thursday, 31 January 2019 at 01:30:36 UTC, Arun Chandrasekaran 
wrote:
 On Wed, Jan 30, 2019 at 5:15 PM Walter Bright via Digitalmars-d 
 <digitalmars-d puremagic.com> wrote:
 On 1/30/2019 4:08 PM, Andrei Alexandrescu wrote:
 Don't forget "typename" and "::template", beautifully 
 combined here:

 typedef typename Allocator::template rebind<Mapped>::other 
 mapped_type_allocator;
It is indeed beautiful. Want to write a DIP to switch to < > ?
Bauss will win another worst code contest if this DIP gets approved ;-)
I can't wait! ;)
Jan 31 2019
parent reply "H. S. Teoh" <hsteoh quickfur.ath.cx> writes:
On Thu, Jan 31, 2019 at 01:13:29PM +0000, bauss via Digitalmars-d wrote:
 On Thursday, 31 January 2019 at 01:30:36 UTC, Arun Chandrasekaran wrote:
 On Wed, Jan 30, 2019 at 5:15 PM Walter Bright via Digitalmars-d
 <digitalmars-d puremagic.com> wrote:
 
 On 1/30/2019 4:08 PM, Andrei Alexandrescu wrote:
 Don't forget "typename" and "::template", beautifully combined
 here:

 typedef typename Allocator::template rebind<Mapped>::other
 mapped_type_allocator;
It is indeed beautiful. Want to write a DIP to switch to < > ?
Bauss will win another worst code contest if this DIP gets approved ;-)
I can't wait! ;)
One of these days I'm gonna hafta pull an IODCC entry... Like the monstrosity I recently posted in bauss's thread. :-D T -- Give a man a fish, and he eats once. Teach a man to fish, and he will sit forever.
Jan 31 2019
parent bauss <jj_1337 live.dk> writes:
On Thursday, 31 January 2019 at 17:31:02 UTC, H. S. Teoh wrote:
 On Thu, Jan 31, 2019 at 01:13:29PM +0000, bauss via 
 Digitalmars-d wrote:
 On Thursday, 31 January 2019 at 01:30:36 UTC, Arun 
 Chandrasekaran wrote:
 On Wed, Jan 30, 2019 at 5:15 PM Walter Bright via 
 Digitalmars-d <digitalmars-d puremagic.com> wrote:
 
 On 1/30/2019 4:08 PM, Andrei Alexandrescu wrote:
 Don't forget "typename" and "::template", beautifully 
 combined here:

 typedef typename Allocator::template 
 rebind<Mapped>::other mapped_type_allocator;
It is indeed beautiful. Want to write a DIP to switch to <
 ?
Bauss will win another worst code contest if this DIP gets approved ;-)
I can't wait! ;)
One of these days I'm gonna hafta pull an IODCC entry... Like the monstrosity I recently posted in bauss's thread. :-D T
Please make my dream come true
Feb 01 2019
prev sibling parent "H. S. Teoh" <hsteoh quickfur.ath.cx> writes:
On Wed, Jan 30, 2019 at 01:28:39PM -0800, H. S. Teoh via Digitalmars-d wrote:
[...]
 	myFunc<T, U>(a, b);
[...] OK, so I decided to amuse myself a little today, and worked out the fully-compilable C++ code that showcases exactly the above line doing something completely different from what you might think it does. First, take a look at main() at the bottom, especially the last two lines. Now see if you can figure out what they do. Compile and run it yourself to find out what it actually does. :-D Now imagine if you inherited this code from an ex-employee and are now responsible for maintaining it. Good luck! -----------------------------------snip------------------------------------ // Totally evil example of why C++ template syntax and free-for-all operator // overloading is a Bad, Bad Idea. #include <iostream> struct Bad { }; struct B { }; struct A { Bad operator,(B b) { return Bad(); } }; struct D { }; struct Ugly { D operator>(Bad b) { return D(); } } U; struct Terrible { } T; struct Evil { ~Evil() { std::cout << "Hard drive reformatted." << std::endl; } }; struct Nasty { Evil operator,(D d) { return Evil(); } }; struct Idea { void operator()(A a, B b) { std::cout << "Good idea, data saved." << std::endl; } Nasty operator<(Terrible t) { return Nasty(); } } gun; template<typename T, typename U> void fun(A a, B b) { std::cout << "Have fun!" << std::endl; } int main() { A a; B b; // What do these lines do? fun<A, B>(a, b); gun<T, U>(a, b); } -----------------------------------snip------------------------------------ T -- To provoke is to call someone stupid; to argue is to call each other stupid.
Jan 30 2019
prev sibling parent reply Walter Bright <newshound2 digitalmars.com> writes:
On 1/30/2019 12:12 PM, H. S. Teoh wrote:
 Please, let's leave C++'s < > mistake in the dustbins of history. Such
 suffering ought not be inflicted upon our future generations.
To pile it on, C++ iostreams overloads << and >> operators.
Jan 30 2019
parent "H. S. Teoh" <hsteoh quickfur.ath.cx> writes:
On Wed, Jan 30, 2019 at 01:54:47PM -0800, Walter Bright via Digitalmars-d wrote:
 On 1/30/2019 12:12 PM, H. S. Teoh wrote:
 Please, let's leave C++'s < > mistake in the dustbins of history.
 Such suffering ought not be inflicted upon our future generations.
To pile it on, C++ iostreams overloads << and >> operators.
Sigh, you made me do it. Couldn't resist: #include <iostream> struct Sigh { }; struct You { Sigh operator>>(std::string s) { return Sigh(); } } U; struct Me { }; struct Do { Me operator<(Sigh m) { return Me(); } } traits; struct It { } T; struct Couldnt { void operator,(Me i) { std::cout << "Goodbye, earth" << std::endl; } }; struct Resist { void operator()(std::string msg) { std::cout << msg << std::endl; } Couldnt operator<(It t) { return Couldnt(); } } fun; int main() { // What does this line do? fun<T, traits<U>>("Hello world"); } :-D T -- Never trust an operating system you don't have source for! -- Martin Schulze
Jan 30 2019
prev sibling parent Patrick Schluter <Patrick.Schluter bbox.fr> writes:
On Wednesday, 30 January 2019 at 19:17:38 UTC, dronord wrote:
 Hello!

 Thanks for best language syntax! But templates.

 Templates are traditional is {} or <>.

 !(exclamation mark) sense/perceive as stop symbol, by my mean.

 < and > is nice construction. May be add it in D?)

 Again, big thanks for language!
< and > used as brackets is completely brain dead. Here a little example in C++ showing why fon< fun< 1 >>::three >::two >::one what doas it mean? (i.e. how is it parsed). Answer: it depends. It doesn't parse the same under C++98 or C++11. fon< fun< 1 >>::three >::two >::one // in C++98 ----------- ----------------------- ----------------------------------- and fon< fun< 1 >>::three >::two >::one // in C++11 -------- --------------------- ---------------------------- ----------------------------------- and to avoid this catastrophic parsing nightmare, D chose a syntax that is not ambiguous. https://gustedt.wordpress.com/2013/12/18/right-angle-brackets-shifting-semantics/#more-2083
Jan 30 2019