www.digitalmars.com         C & C++   DMDScript  

D - template instantiation (suggestion)

reply Heretic <Heretic_member pathlink.com> writes:
yo again. i`ve finally read the D language specification, lol. the more i read
bout d, the better it seems. however there`s one thing that annoys me.
templates have to be instantiated with the "instance Name(ARG)" expression... i
dont quite like it, wouldnt it be better to use Name<ARG> ? it is still context
independent and much faster to type, more comfortable and stuff. in c++ i have a
function alias_cast<T>(char*) that works as a object reference. i add aliases to
objects, but not aliases in teh D way. i name objects with character strings and
i`m able to access them this way. in D, i`d have to write instance
alias_cast(T).f(char*) whis is quite tedious to type and is less clear :/
maybe i`m missing something, pls correct me then, but consider my suggestion of
using the triangular braces for template instantiation...
Dec 01 2003
next sibling parent reply Andy Friesen <andy ikagames.com> writes:
Heretic wrote:
 yo again. i`ve finally read the D language specification, lol. the more i read
 bout d, the better it seems. however there`s one thing that annoys me.
 templates have to be instantiated with the "instance Name(ARG)" expression... i
 dont quite like it, wouldnt it be better to use Name<ARG> ? it is still context
 independent and much faster to type, more comfortable and stuff. in c++ i have
a
 function alias_cast<T>(char*) that works as a object reference. i add aliases
to
 objects, but not aliases in teh D way. i name objects with character strings
and
 i`m able to access them this way. in D, i`d have to write instance
 alias_cast(T).f(char*) whis is quite tedious to type and is less clear :/
 maybe i`m missing something, pls correct me then, but consider my suggestion of
 using the triangular braces for template instantiation...

The trouble with Name<ARG> is (as I understand it) that it requires semantic analysis to figure out whether < and > are being used as angle brackets, or as greater-than/less-than in an expression. Plain-old parenths might cut it, but that makes what's going on less obvious. Braces already have meaning as well. I agree that template instantiation should be much less verbose; it's just a matter of working out a good syntax for it. -- andy
Dec 01 2003
next sibling parent reply "Ben Hinkle" <bhinkle4 juno.com> writes:
"Andy Friesen" <andy ikagames.com> wrote in message
news:bqfm1p$14ks$1 digitaldaemon.com...
 Heretic wrote:
 yo again. i`ve finally read the D language specification, lol. the more


 bout d, the better it seems. however there`s one thing that annoys me.
 templates have to be instantiated with the "instance Name(ARG)"


 dont quite like it, wouldnt it be better to use Name<ARG> ? it is still


 independent and much faster to type, more comfortable and stuff. in c++


 function alias_cast<T>(char*) that works as a object reference. i add


 objects, but not aliases in teh D way. i name objects with character


 i`m able to access them this way. in D, i`d have to write instance
 alias_cast(T).f(char*) whis is quite tedious to type and is less clear


 maybe i`m missing something, pls correct me then, but consider my


 using the triangular braces for template instantiation...

The trouble with Name<ARG> is (as I understand it) that it requires semantic analysis to figure out whether < and > are being used as angle brackets, or as greater-than/less-than in an expression.

Plus in C++ "foo<bar<T>>" needs to be "foo<bar<T> >" with a space between the last two >'s since >> is the right-shift operator. This is a nasty gotcha.
 Plain-old parenths might cut it, but that makes what's going on less
 obvious.  Braces already have meaning as well.

 I agree that template instantiation should be much less verbose; it's
 just a matter of working out a good syntax for it.

   -- andy

Dec 01 2003
parent "Sean L. Palmer" <palmer.sean verizon.net> writes:
C# 2.0 has managed to address that little problem.  It's not unsolvable.

Sean

"Ben Hinkle" <bhinkle4 juno.com> wrote in message
news:bqfq0a$1bl9$1 digitaldaemon.com...
 Plus in C++ "foo<bar<T>>" needs to be "foo<bar<T> >" with a space between
 the last two >'s since >> is the right-shift operator. This is a nasty
 gotcha.

Dec 01 2003
prev sibling parent reply Patrick Down <Patrick_member pathlink.com> writes:
In article <bqfm1p$14ks$1 digitaldaemon.com>, Andy Friesen says...
Heretic wrote:
 yo again. i`ve finally read the D language specification, lol. the more i read
 bout d, the better it seems. however there`s one thing that annoys me.
 templates have to be instantiated with the "instance Name(ARG)" expression... i
 dont quite like it, wouldnt it be better to use Name<ARG> ? it is still context
 independent and much faster to type, more comfortable and stuff. in c++ i have
a
 function alias_cast<T>(char*) that works as a object reference. i add aliases
to
 objects, but not aliases in teh D way. i name objects with character strings
and
 i`m able to access them this way. in D, i`d have to write instance
 alias_cast(T).f(char*) whis is quite tedious to type and is less clear :/
 maybe i`m missing something, pls correct me then, but consider my suggestion of
 using the triangular braces for template instantiation...

The trouble with Name<ARG> is (as I understand it) that it requires semantic analysis to figure out whether < and > are being used as angle brackets, or as greater-than/less-than in an expression. Plain-old parenths might cut it, but that makes what's going on less obvious. Braces already have meaning as well. I agree that template instantiation should be much less verbose; it's just a matter of working out a good syntax for it.

If we are going to keep explicit instantiation I think it would be good to replace the instance keyword with a symbol like '$' template Foo(Type) { void Bar(Type a) { } } $Foo(int).Bar(12); alias $Foo(int).Bar BarInt;
Dec 01 2003
next sibling parent reply "Charles Sanders" <sanders-consulting comcast.net> writes:
Cool idea!  $ feels a little to much like 'interpolation' to me, but this
sounds very cool ( if we want to keep the explicit , why do we want this
again ?  I dont use templates that much sry )

C

"Patrick Down" <Patrick_member pathlink.com> wrote in message
news:bqftct$1gqe$1 digitaldaemon.com...
 In article <bqfm1p$14ks$1 digitaldaemon.com>, Andy Friesen says...
Heretic wrote:
 yo again. i`ve finally read the D language specification, lol. the more



 bout d, the better it seems. however there`s one thing that annoys me.
 templates have to be instantiated with the "instance Name(ARG)"



 dont quite like it, wouldnt it be better to use Name<ARG> ? it is still



 independent and much faster to type, more comfortable and stuff. in c++



 function alias_cast<T>(char*) that works as a object reference. i add



 objects, but not aliases in teh D way. i name objects with character



 i`m able to access them this way. in D, i`d have to write instance
 alias_cast(T).f(char*) whis is quite tedious to type and is less clear



 maybe i`m missing something, pls correct me then, but consider my



 using the triangular braces for template instantiation...

The trouble with Name<ARG> is (as I understand it) that it requires semantic analysis to figure out whether < and > are being used as angle brackets, or as greater-than/less-than in an expression. Plain-old parenths might cut it, but that makes what's going on less obvious. Braces already have meaning as well. I agree that template instantiation should be much less verbose; it's just a matter of working out a good syntax for it.

If we are going to keep explicit instantiation I think it would be good to replace the instance keyword with a symbol like '$' template Foo(Type) { void Bar(Type a) { } } $Foo(int).Bar(12); alias $Foo(int).Bar BarInt;

Dec 01 2003
next sibling parent reply davepermen <davepermen_member pathlink.com> writes:
i don't want to keep it explicit with a keyword or token.

oh, and i want to get rid of templates that are like namespaces. eighter we get
namespaces, and can add template parameters to it, or no namespaces at all.

namespaces or not, i want templates for functions, and for classes.

instance Swap(int).call(a,b); is just plain stupid..

instance(int) swap(a,b); would be nice, for example..

but

swap(a,b); is still unbeatable....


oh, and have i said i'd like to promote a swap operator?

a <=> b; //swaps a and b


now THAT was offtopic:D




In article <bqfu00$1hlj$1 digitaldaemon.com>, Charles Sanders says...
Cool idea!  $ feels a little to much like 'interpolation' to me, but this
sounds very cool ( if we want to keep the explicit , why do we want this
again ?  I dont use templates that much sry )

C

"Patrick Down" <Patrick_member pathlink.com> wrote in message
news:bqftct$1gqe$1 digitaldaemon.com...
 In article <bqfm1p$14ks$1 digitaldaemon.com>, Andy Friesen says...
Heretic wrote:
 yo again. i`ve finally read the D language specification, lol. the more



 bout d, the better it seems. however there`s one thing that annoys me.
 templates have to be instantiated with the "instance Name(ARG)"



 dont quite like it, wouldnt it be better to use Name<ARG> ? it is still



 independent and much faster to type, more comfortable and stuff. in c++



 function alias_cast<T>(char*) that works as a object reference. i add



 objects, but not aliases in teh D way. i name objects with character



 i`m able to access them this way. in D, i`d have to write instance
 alias_cast(T).f(char*) whis is quite tedious to type and is less clear



 maybe i`m missing something, pls correct me then, but consider my



 using the triangular braces for template instantiation...

The trouble with Name<ARG> is (as I understand it) that it requires semantic analysis to figure out whether < and > are being used as angle brackets, or as greater-than/less-than in an expression. Plain-old parenths might cut it, but that makes what's going on less obvious. Braces already have meaning as well. I agree that template instantiation should be much less verbose; it's just a matter of working out a good syntax for it.

If we are going to keep explicit instantiation I think it would be good to replace the instance keyword with a symbol like '$' template Foo(Type) { void Bar(Type a) { } } $Foo(int).Bar(12); alias $Foo(int).Bar BarInt;


Dec 01 2003
next sibling parent "Sean L. Palmer" <palmer.sean verizon.net> writes:
Actually I've been wishing lately for template namespaces in C++.  ;)

I want a swap, min, and max operator.

swap:     a <=> b;
min:   smaller = a <? b;
max:   larger = a >? b;

And yes I want to be able to overload them.

I may want an overloadable abs operator as well.

abs:  magnitude = |+| a;

In C++ I'm overloading unary plus to do this.  ;)

Sean

"davepermen" <davepermen_member pathlink.com> wrote in message
news:bqfvdu$1jqp$1 digitaldaemon.com...
 i don't want to keep it explicit with a keyword or token.

 oh, and i want to get rid of templates that are like namespaces. eighter

 namespaces, and can add template parameters to it, or no namespaces at

 namespaces or not, i want templates for functions, and for classes.

 instance Swap(int).call(a,b); is just plain stupid..

 instance(int) swap(a,b); would be nice, for example..

 but

 swap(a,b); is still unbeatable....


 oh, and have i said i'd like to promote a swap operator?

 a <=> b; //swaps a and b


 now THAT was offtopic:D

Dec 01 2003
prev sibling parent reply Hauke Duden <H.NS.Duden gmx.net> writes:
davepermen wrote:
 i don't want to keep it explicit with a keyword or token.

 oh, and i want to get rid of templates that are like namespaces. eighter we get
 namespaces, and can add template parameters to it, or no namespaces at all.

 namespaces or not, i want templates for functions, and for classes.
 
 instance Swap(int).call(a,b); is just plain stupid..
 
 instance(int) swap(a,b); would be nice, for example..
 
 but
 
 swap(a,b); is still unbeatable....

I agree completely, with all your points! The instance() form of instantiation is a nuisance that I never understood the need for. Is it just because the are no unambiguous parantheses "left"? I'm sure we can find some unused token to replace the <>! If you use templates a lot then all this "instance" stuff becomes starts getting on your nerves quickly. And it doesn't exactly make the code more readable either... Oh, and can't we please have implicit instantiation? This is a very powerful feature that goes a long way to enable you to enhance the built-in language facilities. Is it that hard to implement? And while I'm at it: the namespaces may sound nice in theory - making templates generic constructs that you can put almost anything into - but in practice they make the code less readable. For example, templates are most often used in collection classes. If you're writing a single collection class, then you face a naming problem: what should the name of the namespace be and then what do you call the class? If templates stay the way they are now, then I'm prediciting that we will see a lot of the following in D: template TLinkedList(T) { class TheClass { ... } } You have to give your class two names! One for that obligatory namespace and one for the class itself. And you have to specify both names when you use it ... pretty burdensome, if you ask me. And no, typedefs do not really provide much of a help here either, because it is in the nature of templates that they are written without knowing the types that they are going to be used with. So adding dozens of typedefs of the form typedef instance TLinkedList(int).TheClass TLinkedList_Int; typedef instance TLinkedList(MyClassA).TheClass TLinkedList_MyClassA; typedef instance TLinkedList(MyClassB).TheClass TLinkedList_MyClassB; is out of the question. Besides, the manual name mangling that would be required for such typedefs isn't exactly a property you'd expect from a modern language. There may be uses for template namespaces, but personally I never found myself wishing for that feature in C++. If the namespace was optional, then it would be a nice "icing on the cake" feature, but the way it is now it is a nuisance. Couldn't the template and class definition be merged? Like template class TLinkedList(T) { ... } as a synonym for template <currentnamespace>(T) { class TLinkedList { } } Hoping this post doesn't sound too negative. I just think these issues are too important for the language to just let them pass... Hauke
Dec 01 2003
next sibling parent Georg Wrede <Georg_member pathlink.com> writes:
In article <bqg9gu$23bd$1 digitaldaemon.com>, Hauke Duden says...
davepermen wrote:
 instance Swap(int).call(a,b); is just plain stupid..
 instance(int) swap(a,b); would be nice, for example..
 but
 swap(a,b); is still unbeatable....

I agree completely, with all your points!

I think this would be a great step towards real genericity in practice! I wonder, would this be unreasonably hard to implement?
The instance() form of instantiation is a nuisance that I never 
understood the need for. Is it just because the are no unambiguous 
parantheses "left"? I'm sure we can find some unused token to replace 
the <>! If you use templates a lot then all this "instance" stuff 
becomes starts getting on your nerves quickly. And it doesn't exactly 
make the code more readable either...

For all I know, this instance() thing may have been a natural consequence of templates originally having been a preprcessor- only thing. Genericity was so separate from the language and the compiler that it may have been only natural not to come to think of this as the ultimate goal at the time.
Oh, and can't we please have implicit instantiation? This is a very 
powerful feature that goes a long way to enable you to enhance the 
built-in language facilities. Is it that hard to implement?

Implicit instantiation was another thing, IMHO, that just wasn't even theoretically possible when Stepanov was at it. I could bet my last penny on that it'd have been there right from the start, had they ever known how.
Dec 01 2003
prev sibling parent Antti =?iso-8859-1?Q?Syk=E4ri?= <jsykari gamma.hut.fi> writes:
In article <bqg9gu$23bd$1 digitaldaemon.com>, Hauke Duden wrote:
 davepermen wrote:
 swap(a,b); is still unbeatable....

I agree completely, with all your points! The instance() form of instantiation is a nuisance that I never understood the need for. Is it just because the are no unambiguous parantheses "left"? I'm sure we can find some unused token to replace the <>! If you use templates a lot then all this "instance" stuff

Maybe replacing <> with something else is not the way to go at all... at least if you look at where Java and C# are going to. Having a template syntax _different_ from <> will at any case make D an oddball in the eyes of many programmers.
 And while I'm at it: the namespaces may sound nice in theory - making 
 templates generic constructs that you can put almost anything into - but 
 in practice they make the code less readable.

True. At least if you're accustomed to the C++ way. In C++, you *have* to make your templates classes -- even if class wasn't the proper way to structure the code in the first place. This is similar to Java, which actually forces you to make *all* modules classes, even when they don't have generic arguments! In fact, Java is more consistent than C++ because there isn't anything (functions, enums, ...) that you *couldn't* genericize! Classes are the beginning and the end of all. We are the Class. You will be ... classimilated. This isn't to say that the D template approach is totally right. In D, you can template anything *except* the things that you usually want to template: classes, functions (with implicit instantiation, s'il vous plaît), typedefs (which are sorely missing in -- current -- C++!)...
 For example, templates are most often used in collection classes. If 
 you're writing a single collection class, then you face a naming 
 problem: what should the name of the namespace be and then what do you 
 call the class?
 
 If templates stay the way they are now, then I'm prediciting that we 
 will see a lot of the following in D:
 
 template TLinkedList(T)
 {
 	class TheClass
 	{
 	...
 	}
 }

True.
 You have to give your class two names! One for that obligatory namespace 
 and one for the class itself. And you have to specify both names when 
 you use it ... pretty burdensome, if you ask me.

True.
 And no, typedefs do not really provide much of a help here either, 
 because it is in the nature of templates that they are written without 
 knowing the types that they are going to be used with. So adding dozens 
 of typedefs of the form
 
 typedef instance TLinkedList(int).TheClass TLinkedList_Int;
 typedef instance TLinkedList(MyClassA).TheClass TLinkedList_MyClassA;
 typedef instance TLinkedList(MyClassB).TheClass TLinkedList_MyClassB;
 
 is out of the question. Besides, the manual name mangling that would be 
 required for such typedefs isn't exactly a property you'd expect from a 
 modern language.

True.
 There may be uses for template namespaces, but personally I never found 
 myself wishing for that feature in C++. If the namespace was optional, 
 then it would be a nice "icing on the cake" feature, but the way it is 
 now it is a nuisance.

I found one place where it would be convenient if a module had generic arguments, using syntax not particularly C++ nor D: enum Byte_Order { little_endian, big_endian } module Endian<Byte_Order byte_order> { T fetch<T : Arithmetic_Type>(const byte* data) { // fetch result from address data assuming byte order byte_order } void store<T : Arithmetic_Type>(T value, byte* data) { // store value to address data assuming byte order byte_order } } Then I could use Endian<little_endian>.fetch<int>(address) to get a value from address assuming it's stored in little endian, and Endian<big_endian>.store(value, address) to store it in big endian form. But ah well, this is just cosmetic stuff. I can just as well use a templated class in C++, with two static functions, or two free-standing functions. It's just that the Endian module isn't really *conceptually* a class. I guess you could find a lot of modules that you'd want to templatize, if you'd start doing some serious metaprogramming stuff.
 Couldn't the template and class definition be merged? Like
 
 template class TLinkedList(T)
 {
 	...
 }
 
 as a synonym for
 
 template <currentnamespace>(T)
 {
 	class TLinkedList
 	{
 	}
 }

I like this proposal. It would be nice to get templatized functions, typedefs, aliases and even enums with the same syntax. Hypothetical stupid example: template class TLinkedListSynchronized(T) { ...} template class TLinkedListSingleThreaded(T) { ...} version (SingleThreaded) { template alias TLinkedListMultiThreaded(T) LinkedList(T); } version (MultiThreaded) { template alias TLinkedListSynchronized(T) LinkedList(T); } If this proves difficult to parse, then put the argument list after the keyword "template": template(T) class LinkedList { ... } template(T) T min(T a, T b) { return a < b ? a : b; } I don't know what you'd use template enums for, but why not allow them if you allow everything else?
 Hoping this post doesn't sound too negative. I just think these issues 
 are too important for the language to just let them pass...

True. Generic programming is an essential feature for an industry standard programming language. Metaprogramming will be the next big step. If one could make *that* leap, one might get generic programming for free as a side effect. But that won't happen in a couple of years... -Antti
Dec 03 2003
prev sibling next sibling parent reply Antti =?iso-8859-1?Q?Syk=E4ri?= <jsykari gamma.hut.fi> writes:
In article <bqfu00$1hlj$1 digitaldaemon.com>, Charles Sanders wrote:
 Cool idea!  $ feels a little to much like 'interpolation' to me, but this
 sounds very cool ( if we want to keep the explicit , why do we want this
 again ?  I dont use templates that much sry )

To me, $ feels for some reason like perl... -Antti
Dec 01 2003
parent reply "Charles Sanders" <sanders-consulting comcast.net> writes:
Yea, and PHP, where print "$foo"; prints the value of the variable foo (
interpolation they call it ) .

C

"Antti Sykäri" <jsykari gamma.hut.fi> wrote in message
news:slrnbsn8c6.17n.jsykari pulu.hut.fi...
 In article <bqfu00$1hlj$1 digitaldaemon.com>, Charles Sanders wrote:
 Cool idea!  $ feels a little to much like 'interpolation' to me, but


 sounds very cool ( if we want to keep the explicit , why do we want this
 again ?  I dont use templates that much sry )

To me, $ feels for some reason like perl... -Antti

Dec 01 2003
parent reply "Mark J. Brudnak" <mjbrudna oakland.edu> writes:
IMO '$' should be reserved to denote the end of an array in the slice
operation.

SomeType array[ SOME_NUMBER ] ;

array[0..$] ; /* slices the whole array */
array[$-2..$] /* slices the last three elements */

Mark.


"Charles Sanders" <sanders-consulting comcast.net> wrote in message
news:bqg79k$1vpi$1 digitaldaemon.com...
 Yea, and PHP, where print "$foo"; prints the value of the variable foo (
 interpolation they call it ) .

 C

 "Antti Sykäri" <jsykari gamma.hut.fi> wrote in message
 news:slrnbsn8c6.17n.jsykari pulu.hut.fi...
 In article <bqfu00$1hlj$1 digitaldaemon.com>, Charles Sanders wrote:
 Cool idea!  $ feels a little to much like 'interpolation' to me, but


 sounds very cool ( if we want to keep the explicit , why do we want



 again ?  I dont use templates that much sry )

To me, $ feels for some reason like perl... -Antti


Dec 01 2003
next sibling parent reply Ant <Ant_member pathlink.com> writes:
In article <bqgclt$2843$1 digitaldaemon.com>, Mark J. Brudnak says...
IMO '$' should be reserved to denote the end of an array in the slice
operation.

SomeType array[ SOME_NUMBER ] ;

array[0..$] ; /* slices the whole array */
array[$-2..$] /* slices the last three elements */

Mark.

IMO you opinion is realy cool. Ant
Dec 01 2003
parent jonth ccpgames.com writes:
In article <bqgdrs$29u1$1 digitaldaemon.com>, Ant says...
In article <bqgclt$2843$1 digitaldaemon.com>, Mark J. Brudnak says...
IMO '$' should be reserved to denote the end of an array in the slice
operation.

SomeType array[ SOME_NUMBER ] ;

array[0..$] ; /* slices the whole array */
array[$-2..$] /* slices the last three elements */

Mark.

IMO you opinion is realy cool. Ant

IMO why not use the same syntax as Python? array[:] a slice of the whole array array[-5:] last five elements array[:-5] all but last five Also D should have this: In article <bqgdrs$29u1$1 digitaldaemon.com>, Ant says...
In article <bqgclt$2843$1 digitaldaemon.com>, Mark J. Brudnak says...
IMO '$' should be reserved to denote the end of an array in the slice
operation.

SomeType array[ SOME_NUMBER ] ;

array[0..$] ; /* slices the whole array */
array[$-2..$] /* slices the last three elements */

Mark.

IMO you opinion is realy cool. Ant

IMO use the same syntax as Python, skip the perlin noise? or use .. if you insist ;-) but it's two keypresses rather than 1 array[:] // a slice of the whole array array[-5:] // last five elements array[:-5] // all but last five And D should also have this: some = array[-2] //next to last component this is absolutely beautiful if you have a circular list or something and have to do something based on other members. /* foreach(int i, inout float f; a) { //this will overstep the bounds so we need a special case for the last two f = (a[i+1] + a[i+2])*0.5 } */ foreach(int i, float f; a) { //instead we start at the next to latest a[i-2] = (a[i-1] + a[i])*0.5 } Nonni
Dec 03 2003
prev sibling next sibling parent reply davepermen <davepermen_member pathlink.com> writes:
IMO '$' should be reserved to denote the end of an array in the slice
operation.

SomeType array[ SOME_NUMBER ] ;

array[0..$] ; /* slices the whole array */
array[$-2..$] /* slices the last three elements */

Mark.

why? nothing is shorter than $. and i really mean NOTHING! :D array[x..] == your array[x..$] array[..x] == your array[0..x] array[..] == your array[0..$] == array[] would be best..
Dec 01 2003
parent reply "Mark Brudnak" <malibrud provide.net> writes:
"davepermen" <davepermen_member pathlink.com> wrote in message
news:bqgebg$2ank$1 digitaldaemon.com...
IMO '$' should be reserved to denote the end of an array in the slice
operation.

SomeType array[ SOME_NUMBER ] ;

array[0..$] ; /* slices the whole array */
array[$-2..$] /* slices the last three elements */

Mark.

why? nothing is shorter than $. and i really mean NOTHING! :D array[x..] == your array[x..$] array[..x] == your array[0..x] array[..] == your array[0..$] == array[] would be best..

What about the case: array[$-2..$] /* slices the last three elements */ in your notation?

Dec 01 2003
parent reply Ilya Minkov <minkov cs.tum.edu> writes:
Mark Brudnak wrote:
 What about the case:
 
 array[$-2..$] /* slices the last three elements */

array[-2..] with the limitation, that this minus may not be a part of the argument, but only a unary minus. Hell, make it a "[-"-operator! A negative value of arguments should be still out-of-bounds error. -eye
Dec 03 2003
parent reply Jon Thoroddsen <Jon_member pathlink.com> writes:
In article <bqlhgf$mr7$1 digitaldaemon.com>, Ilya Minkov says...
Mark Brudnak wrote:
 What about the case:
 
 array[$-2..$] /* slices the last three elements */

array[-2..] with the limitation, that this minus may not be a part of the argument, but only a unary minus. Hell, make it a "[-"-operator! A negative value of arguments should be still out-of-bounds error. -eye

I much prefer ":" as it's more concise, and i'm allergic to Pascal, I think. array[:] // a slice of the whole array array[-5:] // last five elements array[:-5] // all but last five And contrary to what Ilya says, D should definitely steal this from Python: some = array[-2] //next to last component this is absolutely beautiful if you have a circular list or something and have to do something based on other members. Convolution type things. /* foreach(int i, inout float f; a) { //this will overstep the bounds so we need a special case for the last two f = (a[i+1] + a[i+2])*0.5 } */ foreach(int i, float f; a) { //instead we start at the next to latest a[i-2] = (a[i-1] + a[i])*0.5 } Nonni PS: sorry for (more or less) reposting, but last time got garbled, and this fit even better here.
Dec 03 2003
next sibling parent reply Ilya Minkov <Ilya_member pathlink.com> writes:
In article <bqlvrg$1cft$1 digitaldaemon.com>, Jon Thoroddsen says...

I much prefer ":" as it's more concise, and i'm allergic to Pascal, I think.

Call it "much" more concise. :)
array[:]   // a slice of the whole array
array[-5:] // last five elements
array[:-5] // all but last five

These ones should all work with my proposal, as - would be a unary operator right within this expression. Whatever variable is here in place of your "5" should be nontheless positive.
And contrary to what Ilya says, D should definitely steal this from Python:

It's not exactly my opinion i was stating, i was just looking for a compromise. Walter is strongly against a forced neg check at runtime for every array access, since this is bad for performance. And we *really* want to rival not only with Java, but also with C++. ;) So i propose that whenever it is possible to derive that negativity from expression syntax, it should be done, else it is an error.
some = array[-2] //next to last component

This would work.
this is absolutely beautiful if you have a circular list or something and have
to do something based on other members. Convolution type things.

--- 8< --- >8 --- Walter is against real circularity. It has to be exceptionally rare, whereas acessing the n-th element from the end is very common and i would wish there be some neat syntactic way to express it. However, it's not really a problem if there isn't. There ought to be quite more serious issues. -eye
Dec 04 2003
parent "Sean L. Palmer" <palmer.sean verizon.net> writes:
"Ilya Minkov" <Ilya_member pathlink.com> wrote in message
news:bqno46$trs$1 digitaldaemon.com...
 In article <bqlvrg$1cft$1 digitaldaemon.com>, Jon Thoroddsen says...

I much prefer ":" as it's more concise, and i'm allergic to Pascal, I


 Call it "much" more concise. :)

array[:]   // a slice of the whole array
array[-5:] // last five elements
array[:-5] // all but last five

These ones should all work with my proposal, as - would be a unary

 right within this expression. Whatever variable is here in place of your

 should be nontheless positive.

And contrary to what Ilya says, D should definitely steal this from


 It's not exactly my opinion i was stating, i was just looking for a

 Walter is strongly against a forced neg check at runtime for every array

 since this is bad for performance. And we *really* want to rival not only

 Java, but also with C++. ;) So i propose that whenever it is possible to

 that negativity from expression syntax, it should be done, else it is an

True true. You probably already said this, Ilya, but it would seem that in this context, there should be [- and :- tokens, or that somehow the unary minus is not lexically part of some int literal. I think this is already the case. It would not be an unreasonable restriction to have the "negativeness" be part of hte expression and not part of the variable. It might be tricky to explain to newbies though. It would have to be in the FAQ. It would be worth having though.
some = array[-2] //next to last component

This would work.
this is absolutely beautiful if you have a circular list or something and


to do something based on other members. Convolution type things.

--- 8< --- >8 --- Walter is against real circularity. It has to be exceptionally rare,

 acessing the n-th element from the end is very common and i would wish

 some neat syntactic way to express it. However, it's not really a problem

 there isn't. There ought to be quite more serious issues.

 -eye

Circularity is still best handled with modulo % or and &. You can make your own container that always does modulo on the index. Sean
Dec 04 2003
prev sibling parent reply "Mark J. Brudnak" <mjbrudna oakland.edu> writes:
"Jon Thoroddsen" <Jon_member pathlink.com> wrote

<snip>

 I much prefer ":" as it's more concise, and i'm allergic to Pascal, I

 array[:]   // a slice of the whole array
 array[-5:] // last five elements

This would actually slice the last *six* elements, $-5, $-4, $-3, $-2, $-1, and $
 array[:-5] // all but last five

 And contrary to what Ilya says, D should definitely steal this from

 some = array[-2] //next to last component

This breaks symetry in the notation. In your scheme, first element: array[0] last element: array[-1] To be consistent, it should be: first element: array[0] last element: array[-0] second element: array[1] second to last element: array[-1] but as we know -0 = 0. It this worth the economy of saving one or two key strokes?? Especially since the current situation is int end = arrary.length -1 ; slice = array[end-4..end] ; /* slices the last five elements */ ...or... slice = array[(array.length-5)..(array.length-1)] ; /* slices the last five elements */ It would seem a huge improvment to introduce the $ as a shortcut for "array.length - 1" then slice = array[$-4..$] ; /* slices the last five elements */ We save two keystrokes by using your notation slice = array[-4..] ; /* slices the last five elements */ at the expense of (IMO) clarity.
 this is absolutely beautiful if you have a circular list or something and

 to do something based on other members. Convolution type things.


 /*
 foreach(int i, inout float f; a)
 {
 //this will overstep the bounds so we need a special case for the last two
 f = (a[i+1] + a[i+2])*0.5
 }
 */

 foreach(int i, float f; a)
 {
 //instead we start at the next to latest
 a[i-2] = (a[i-1] + a[i])*0.5
 }

 Nonni

 PS: sorry for (more or less) reposting, but last time got garbled, and

 even better here.

Dec 05 2003
next sibling parent Hauke Duden <H.NS.Duden gmx.net> writes:
Mark J. Brudnak wrote:
array[:]   // a slice of the whole array
array[-5:] // last five elements

This would actually slice the last *six* elements, $-5, $-4, $-3, $-2, $-1, and $

No, not if it works as in Python. In Python, -1 refers to the last element of the array, so a slice starting at -5 consists of the last 5 elements.
 Python:
 
some = array[-2] //next to last component

This breaks symetry in the notation. In your scheme, first element: array[0] last element: array[-1] To be consistent, it should be: first element: array[0] last element: array[-0]

 but as we know -0 = 0.

That's what many programmers think when they see Python slices for the first time. I did too. But it's all just a matter of definition. If you define that indices refer to the left "border" of array slots, then the Python way is the consistent one. Consider the following array (view with fixed width font) | a | b | c | d | ^ ^ ^ 0 -1 -0 a,b,c,d are the values in the array slots, the numbers below are the indices, referring to the left border of the corresponding slot. Viewed like this, -0 would refer to the (non-existent) element following d and -1 refers to d itself. Also, as you point out, if you define -0 as the last element, then you cannot reference it, since -0 = 0. So the Python way is really the only way to do it if you want to avoid having to pass an expression of some kind (like your $-2) instead of an integer value (-2). Also, maybe surprisingly, this system actually works very well in practice. Up to now, I never got confused by the indexing scheme. And I think most Python programmers will agree with that. Hauke
Dec 05 2003
prev sibling parent "Sean L. Palmer" <palmer.sean verizon.net> writes:
"Mark J. Brudnak" <mjbrudna oakland.edu> wrote in message
news:bqq2j3$1av8$1 digitaldaemon.com...
 "Jon Thoroddsen" <Jon_member pathlink.com> wrote
 array[:]   // a slice of the whole array
 array[-5:] // last five elements

This would actually slice the last *six* elements, $-5, $-4, $-3, $-2,

 and $

 array[:-5] // all but last five


Icon apparently does it the same way as Python.
 It this worth the economy of saving one or two key strokes??  Especially
 since the current situation is

 int end = arrary.length -1 ;
 slice = array[end-4..end] ;     /* slices the last five elements */

No, in current DMD this would slice off the four elements just before the last element in the array, not including the last element. Sean
Dec 05 2003
prev sibling parent reply "Sean L. Palmer" <palmer.sean verizon.net> writes:
Sounds good.

Sean

"Mark J. Brudnak" <mjbrudna oakland.edu> wrote in message
news:bqgclt$2843$1 digitaldaemon.com...
 IMO '$' should be reserved to denote the end of an array in the slice
 operation.

 SomeType array[ SOME_NUMBER ] ;

 array[0..$] ; /* slices the whole array */
 array[$-2..$] /* slices the last three elements */

 Mark.

Dec 01 2003
parent Antti =?iso-8859-1?Q?Syk=E4ri?= <jsykari gamma.hut.fi> writes:
Tangenting the issue, I just recently realized (maybe it was
crystal-clear to everybody else, but what the heck) that representing
half-open ranges, which was proposed some time earlier, actually
wouldn't be completely impossible.

array[a .. b) // for (int i=a;    i<b; ++i)
array[a .. b] // for (int i=a;   i<=b; ++i)
array(a .. b) // for (int i=a+1;  i<b; ++i)
array(a .. b] // for (int i=a+1; i<=b; ++i)

I for some reason thought that the language grammar couldn't allow [ and
) to match. Silly me. Just requires adding the proper grammar
productions:

PostfixExpression [ Expression )
PostfixExpression [ Expression ]
PostfixExpression ( Expression )
PostfixExpression ( Expression ]

Ok, so it might conflict a bit with the function call syntax. And would
probably cause a lot of nice off-by-one bugs because ( and [ look the
same. So we may probably forget it :)

-Antti

In article <bqh9vd$h48$1 digitaldaemon.com>, Sean L. Palmer wrote:
 Sounds good.

*nods*
 
 Sean
 
 "Mark J. Brudnak" <mjbrudna oakland.edu> wrote in message
 news:bqgclt$2843$1 digitaldaemon.com...
 IMO '$' should be reserved to denote the end of an array in the slice
 operation.

 SomeType array[ SOME_NUMBER ] ;

 array[0..$] ; /* slices the whole array */
 array[$-2..$] /* slices the last three elements */

 Mark.


Dec 03 2003
prev sibling parent brad beveridge <brad nospam.com> writes:
Maybe slightly OT, but is there a reason that D doesn't support 
automatic deduction of types like C++ does?
ie
template swap(T){
void call(T a, T b){
}
}
would be nice if you could call it like
instance swap(*).call(int,int)
Which would deduce the type of the instance from the parameters.  Or 
better yet, as someone said - remove the templating namespace and have
call(int,int).

Also, I do find the current template syntax slightly clunky, but could 
live with it if deduction was possible :)
ie if something like , alias instance swap(*).call mySwap, was possible 
I'd be happier.

Sorry if this is old ground.

Cheers
Brad
Dec 01 2003
prev sibling next sibling parent "Sean L. Palmer" <palmer.sean verizon.net> writes:
"$" is better than "instance".  Instance is just too wordy.

I feel like the people designing the D templates have never done much
generic programming in C++.

Sean

"Patrick Down" <Patrick_member pathlink.com> wrote in message
news:bqftct$1gqe$1 digitaldaemon.com...
 In article <bqfm1p$14ks$1 digitaldaemon.com>, Andy Friesen says...
Heretic wrote:
 yo again. i`ve finally read the D language specification, lol. the more



 bout d, the better it seems. however there`s one thing that annoys me.
 templates have to be instantiated with the "instance Name(ARG)"



 dont quite like it, wouldnt it be better to use Name<ARG> ? it is still



 independent and much faster to type, more comfortable and stuff. in c++



 function alias_cast<T>(char*) that works as a object reference. i add



 objects, but not aliases in teh D way. i name objects with character



 i`m able to access them this way. in D, i`d have to write instance
 alias_cast(T).f(char*) whis is quite tedious to type and is less clear



 maybe i`m missing something, pls correct me then, but consider my



 using the triangular braces for template instantiation...

The trouble with Name<ARG> is (as I understand it) that it requires semantic analysis to figure out whether < and > are being used as angle brackets, or as greater-than/less-than in an expression. Plain-old parenths might cut it, but that makes what's going on less obvious. Braces already have meaning as well. I agree that template instantiation should be much less verbose; it's just a matter of working out a good syntax for it.

If we are going to keep explicit instantiation I think it would be good to replace the instance keyword with a symbol like '$' template Foo(Type) { void Bar(Type a) { } } $Foo(int).Bar(12); alias $Foo(int).Bar BarInt;

Dec 01 2003
prev sibling parent reply Felix <Felix_member pathlink.com> writes:
Why cannot use simply instancetype(newinstancetype) and the compiler will know
that, if instancetype is a "instance type", then it will instantiate it; and
that's all



In article <bqftct$1gqe$1 digitaldaemon.com>, Patrick Down says...
In article <bqfm1p$14ks$1 digitaldaemon.com>, Andy Friesen says...
Heretic wrote:
 yo again. i`ve finally read the D language specification, lol. the more i read
 bout d, the better it seems. however there`s one thing that annoys me.
 templates have to be instantiated with the "instance Name(ARG)" expression... i
 dont quite like it, wouldnt it be better to use Name<ARG> ? it is still context
 independent and much faster to type, more comfortable and stuff. in c++ i have
a
 function alias_cast<T>(char*) that works as a object reference. i add aliases
to
 objects, but not aliases in teh D way. i name objects with character strings
and
 i`m able to access them this way. in D, i`d have to write instance
 alias_cast(T).f(char*) whis is quite tedious to type and is less clear :/
 maybe i`m missing something, pls correct me then, but consider my suggestion of
 using the triangular braces for template instantiation...

The trouble with Name<ARG> is (as I understand it) that it requires semantic analysis to figure out whether < and > are being used as angle brackets, or as greater-than/less-than in an expression. Plain-old parenths might cut it, but that makes what's going on less obvious. Braces already have meaning as well. I agree that template instantiation should be much less verbose; it's just a matter of working out a good syntax for it.

If we are going to keep explicit instantiation I think it would be good to replace the instance keyword with a symbol like '$' template Foo(Type) { void Bar(Type a) { } } $Foo(int).Bar(12); alias $Foo(int).Bar BarInt;

Dec 01 2003
next sibling parent reply J Anderson <REMOVEanderson badmama.com.au> writes:
Felix wrote:

Why cannot use simply instancetype(newinstancetype) and the compiler will know
that, if instancetype is a "instance type", then it will instantiate it; and
that's all
  

You mean like: template Tfunc(T) { func(T) {} } ... Tfunc(int) X;
Dec 02 2003
parent reply Felix <Felix_member pathlink.com> writes:
Exactly. But I understand the current syntax if it is only experimental one.


In article <bqhmes$13av$1 digitaldaemon.com>, J Anderson says...
Felix wrote:

Why cannot use simply instancetype(newinstancetype) and the compiler will know
that, if instancetype is a "instance type", then it will instantiate it; and
that's all
  

You mean like: template Tfunc(T) { func(T) {} } ... Tfunc(int) X;

Dec 02 2003
parent reply J Anderson <REMOVEanderson badmama.com.au> writes:
Felix wrote:

Exactly. But I understand the current syntax if it is only experimental one.


In article <bqhmes$13av$1 digitaldaemon.com>, J Anderson says...
  

Felix wrote:

    

Why cannot use simply instancetype(newinstancetype) and the compiler will know
that, if instancetype is a "instance type", then it will instantiate it; and
that's all
 

      

You mean like: template Tfunc(T) { func(T) {} } ... Tfunc(int) X;


type of syntactical parsing difficulty. The D compiler is meant to be easy to replicate. -Anderson
Dec 02 2003
parent "Charles Sanders" <sanders-consulting comcast.net> writes:
 I do think Walter would have used the above syntax, if there wasn't some
 type of syntactical parsing difficulty.  The D compiler is meant to be
 easy to replicate.

But at what cost, an cumbersome language ? C "J Anderson" <REMOVEanderson badmama.com.au> wrote in message news:bqifev$2aef$1 digitaldaemon.com...
 Felix wrote:

Exactly. But I understand the current syntax if it is only experimental


In article <bqhmes$13av$1 digitaldaemon.com>, J Anderson says...


Felix wrote:



Why cannot use simply instancetype(newinstancetype) and the compiler




that, if instancetype is a "instance type", then it will instantiate




that's all

You mean like: template Tfunc(T) { func(T) {} } ... Tfunc(int) X;


type of syntactical parsing difficulty. The D compiler is meant to be easy to replicate. -Anderson

Dec 03 2003
prev sibling parent reply Patrick Down <pat codemoon.com> writes:
Felix <Felix_member pathlink.com> wrote in
news:bqhfsl$p7k$1 digitaldaemon.com: 

 Why cannot use simply instancetype(newinstancetype) and the compiler
 will know that, if instancetype is a "instance type", then it will
 instantiate it; and that's all

I agree that would be best. You will have to ask Walter but I belive the reason for the 'instance' keyword is to resolve some context sensitivity issue with the langauge grammer.
Dec 02 2003
parent "Walter" <walter digitalmars.com> writes:
"Patrick Down" <pat codemoon.com> wrote in message
news:Xns944555EF3300Bpatcodemooncom 63.105.9.61...
 Felix <Felix_member pathlink.com> wrote in
 news:bqhfsl$p7k$1 digitaldaemon.com:

 Why cannot use simply instancetype(newinstancetype) and the compiler
 will know that, if instancetype is a "instance type", then it will
 instantiate it; and that's all

I agree that would be best. You will have to ask Walter but I belive the reason for the 'instance' keyword is to resolve some context sensitivity issue with the langauge grammer.

You're right. It would not parse in a context-free manner.
Dec 19 2003
prev sibling parent reply "Achilleas Margaritis" <axilmar b-online.gr> writes:
This is how templates should be declared:

template(A, B, C) class Foo {
    public A a;
    public B b;
    public C c;
}

And this is how templates must be used:

//explicit instantiation
Foo(int, float, double) foo1;

//implicit instantiation
Foo foo2;
foo.A = 5;
foo.B = 5.3;
foo.C = "yo";

Some notes:

1. since the template parameters are arguments to the template class, the
syntax

    <identifier>(<type>) is perfectly justified.

2. In C++, the compiler deduces the types of a template function from its
usage. It is
    possible to do so in classes also.

3. A template should not accept only values and types, but any expression
that
    when it is used, it can be compiled. Templates should be more like
parameterized
    macros. This would enable real generics.

"Heretic" <Heretic_member pathlink.com> wrote in message
news:bqffep$q9u$1 digitaldaemon.com...
 yo again. i`ve finally read the D language specification, lol. the more i

 bout d, the better it seems. however there`s one thing that annoys me.
 templates have to be instantiated with the "instance Name(ARG)"

 dont quite like it, wouldnt it be better to use Name<ARG> ? it is still

 independent and much faster to type, more comfortable and stuff. in c++ i

 function alias_cast<T>(char*) that works as a object reference. i add

 objects, but not aliases in teh D way. i name objects with character

 i`m able to access them this way. in D, i`d have to write instance
 alias_cast(T).f(char*) whis is quite tedious to type and is less clear :/
 maybe i`m missing something, pls correct me then, but consider my

 using the triangular braces for template instantiation...

Dec 01 2003
parent Georg Wrede <Georg_member pathlink.com> writes:
In article <bqg9nn$23m3$1 digitaldaemon.com>, Achilleas Margaritis says...
This is how templates should be declared:

template(A, B, C) class Foo {
    public A a;
    public B b;
    public C c;
}

And this is how templates must be used:

//explicit instantiation
Foo(int, float, double) foo1;

//implicit instantiation
Foo foo2;
foo.A = 5;
foo.B = 5.3;
foo.C = "yo";

I'd have that as Foo foo; foo.a = 5; foo.b = 5.3; foo.c = "yo"; The you could also have template(A, B, C) class Foo { public A aa; public A ab; public B b; public C c; } and Foo foo; foo.aa = 5; foo.ab = 49; foo.b = 5.3; foo.c = "yo";
Dec 01 2003