www.digitalmars.com         C & C++   DMDScript  

D - Template question

reply Chris Sokol <chris echosproject.org> writes:
Hi, I'm trying to build some container templates as a learning exercise, and I
have questions.

In C++, I'd do:

template< typename T >
class DefaultComparator {
static int compare(const T* a, const T* b) { return compare_logic; }
};

template< typename T, typename Comparator = DefaultComparator< T > >
class Tree {
tree_stuff();
};

So I can use the default comparator most of the time, but supply an alternate if
I need.

Does D support this?  How do I do it?
Aug 05 2003
parent reply Patrick Down <Patrick_member pathlink.com> writes:
In article <bgohsh$1erc$1 digitaldaemon.com>, Chris Sokol says...
Hi, I'm trying to build some container templates as a learning exercise, and I
have questions.

In C++, I'd do:

template< typename T >
class DefaultComparator {
static int compare(const T* a, const T* b) { return compare_logic; }
};

template< typename T, typename Comparator = DefaultComparator< T > >
class Tree {
tree_stuff();
};

So I can use the default comparator most of the time, but supply an alternate if
I need.

Does D support this?  How do I do it?
If you could do it at all it would have to be something like the following. If it doesn't work then give Walter a hard time about it because you should be able to do things like this in D. template DefaultComparator(T) { struct Functions { static int compare(const T* a, const T* b) { return compare_logic; } } } template TreeT(T,Comparator) { class Tree { tree_stuff(); } } template TreeT(T) { alias instance TreeT(T,instance DefaultComparator(T)).Tree Tree; }
Aug 05 2003
next sibling parent reply Chris Sokol <chros echosproject.org> writes:
In article <bgosim$1qae$1 digitaldaemon.com>, Patrick Down says...
In article <bgohsh$1erc$1 digitaldaemon.com>, Chris Sokol says...
Hi, I'm trying to build some container templates as a learning exercise, and I
have questions.

In C++, I'd do:

template< typename T >
class DefaultComparator {
static int compare(const T* a, const T* b) { return compare_logic; }
};

template< typename T, typename Comparator = DefaultComparator< T > >
class Tree {
tree_stuff();
};

So I can use the default comparator most of the time, but supply an alternate if
I need.

Does D support this?  How do I do it?
If you could do it at all it would have to be something like the following. If it doesn't work then give Walter a hard time about it because you should be able to do things like this in D. template DefaultComparator(T) { struct Functions { static int compare(const T* a, const T* b) { return compare_logic; } } } template TreeT(T,Comparator) { class Tree { tree_stuff(); } } template TreeT(T) { alias instance TreeT(T,instance DefaultComparator(T)).Tree Tree; }
Wouldn't I then have to use either instance Tree(Foo, FooComparator) t1; or instance TreeT(Foo).Tree t2; ? That seems ugly.
Aug 05 2003
parent Patrick Down <Patrick_member pathlink.com> writes:
In article <bgotee$1r2i$1 digitaldaemon.com>, Chris Sokol says...
In article <bgosim$1qae$1 digitaldaemon.com>, Patrick Down says...
In article <bgohsh$1erc$1 digitaldaemon.com>, Chris Sokol says...
Hi, I'm trying to build some container templates as a learning exercise, and I
have questions.

In C++, I'd do:

template< typename T >
class DefaultComparator {
static int compare(const T* a, const T* b) { return compare_logic; }
};

template< typename T, typename Comparator = DefaultComparator< T > >
class Tree {
tree_stuff();
};

So I can use the default comparator most of the time, but supply an alternate if
I need.

Does D support this?  How do I do it?
If you could do it at all it would have to be something like the following. If it doesn't work then give Walter a hard time about it because you should be able to do things like this in D. template DefaultComparator(T) { struct Functions { static int compare(const T* a, const T* b) { return compare_logic; } } } template TreeT(T,Comparator) { class Tree { tree_stuff(); } } template TreeT(T) { alias instance TreeT(T,instance DefaultComparator(T)).Tree Tree; }
Wouldn't I then have to use either instance Tree(Foo, FooComparator) t1; or instance TreeT(Foo).Tree t2; ? That seems ugly.
Nope instance TreeT(Foo, FooComparator).Tree t1; or instance TreeT(Foo).Tree t2;
Aug 05 2003
prev sibling parent reply Karl Bochert <kbochert copper.net> writes:
 
 If you could do it at all it would have to be something
 like the following.  If it doesn't work then give Walter
 a hard time about it because you should be able to do things
 like this in D.
 
 
 template DefaultComparator(T)
 {
 struct Functions 
 {
 static int compare(const T* a, const T* b) { return compare_logic; }
 }
 }
 
 template TreeT(T,Comparator)
 {
 
 class Tree 
 {
 tree_stuff();
 }
 }
 
 template TreeT(T)
 {
 alias instance TreeT(T,instance DefaultComparator(T)).Tree Tree;
 }
Do any of you wizards comprehend how incomprehensible and ugly that looks to us ordinary programmers? The primary goal of the syntax seems to be to allow the existing parser constructs to handle it easily, rather than understandability.
Aug 05 2003
next sibling parent reply "Matthew Wilson" <matthew stlsoft.org> writes:
"Karl Bochert" <kbochert copper.net> wrote in message
news:1103_1060144968 bose...
 If you could do it at all it would have to be something
 like the following.  If it doesn't work then give Walter
 a hard time about it because you should be able to do things
 like this in D.


 template DefaultComparator(T)
 {
 struct Functions
 {
 static int compare(const T* a, const T* b) { return compare_logic; }
 }
 }

 template TreeT(T,Comparator)
 {

 class Tree
 {
 tree_stuff();
 }
 }

 template TreeT(T)
 {
 alias instance TreeT(T,instance DefaultComparator(T)).Tree Tree;
 }
Do any of you wizards comprehend how incomprehensible and ugly that looks to us ordinary programmers? The primary goal of the syntax seems to be to allow the existing parser constructs to handle it easily, rather than understandability.
Good point. Whilst being *far* from an expert on D's templates, it seems to me that the current situation is arse 'bout face, and the compiler's ability to make unambiguous decisions, which is a good thing, is more important than (i) usability/readability, and (ii) implicit instantiation. This is fallacious. However, I have no answer. Most of the people who appear interested in having templates seem to decry the C++ way of doing things. Maybe once bit vs boolean (I'm with you Burton) and the libraries (anyone with me on that one?) issues are resolved, then this is the most important, and probably deserving of most people's attention. I for one would be very interested to hear in detail (presumably from Walter) the design, functioning and rationale of the current template support, and then get a load of clever template-type people to try and do something non-trivial with the current language. If we cannot create an equivalent to C++'s STL, in power, efficiency and generality, with D's templates, then they are plainly wrong. Matthew
Aug 05 2003
parent reply "Sean L. Palmer" <palmer.sean verizon.net> writes:
"Matthew Wilson" <matthew stlsoft.org> wrote in message
news:bgq1eu$2ukn$1 digitaldaemon.com...
 Do any of you wizards comprehend how incomprehensible and
 ugly that looks to us ordinary programmers?
I agree. I don't think I'm alone... template syntax shouldn't be so bad as that.
 The primary goal of the syntax seems to be to allow the
 existing parser constructs to handle it easily, rather than
 understandability.
Good point. Whilst being *far* from an expert on D's templates, it seems
to
 me that the current situation is arse 'bout face, and the compiler's
ability
 to make unambiguous decisions, which is a good thing, is more important
than
 (i) usability/readability, and (ii) implicit instantiation. This is
 fallacious.

 However, I have no answer. Most of the people who appear interested in
 having templates seem to decry the C++ way of doing things. Maybe once bit
 vs boolean (I'm with you Burton) and the libraries (anyone with me on that
 one?) issues are resolved, then this is the most important, and probably
 deserving of most people's attention.
I doubt you'll get good libraries without good templates.
 I for one would be very interested to hear in detail (presumably from
 Walter) the design, functioning and rationale of the current template
 support, and then get a load of clever template-type people to try and do
 something non-trivial with the current language.
Implicit instantiation causes headaches for the C++ compiler vendor (that's Walter), so D doesn't have implicit instantiation. ;)
 If we cannot create an equivalent to C++'s STL, in power, efficiency and
 generality, with D's templates, then they are plainly wrong.

 Matthew
Well, without implicit instantiation, everything ends up being a lot more of a PITA, and some things just can't be done. For one, you have to know ahead of time that something is a template in order to use it; you can't just use it and have the template parameters inferred from context. This makes template code incompatible with non-template code, in ways that make it difficult to write templates that can work with either templates or non-templates. I've written a lot of C++ templates, and they're powerful, if ugly. D templates seem like they have had their wings clipped, and appear to me to be a strict subset of the C++ template functionality without cleaning up the syntax much. Seems to be a step backwards, to me. I want even more power and more implicitness than what C++ provides. Sean
Aug 08 2003
parent "Matthew Wilson" <matthew stlsoft.org> writes:
 D templates seem like they have had their wings clipped, and appear to me
to
 be a strict subset of the C++ template functionality without cleaning up
the
 syntax much.

 Seems to be a step backwards, to me.  I want even more power and more
 implicitness than what C++ provides.
I'm with you 100%. Since you mentioned my shims article in another post, I might use that as an example of a concept from C++ I'd like to bring to D, and that requires smart templates, and implicit instantiation. We need both!
Aug 08 2003
prev sibling next sibling parent Patrick Down <pat codemoon.com> writes:
Karl Bochert <kbochert copper.net> wrote in news:1103_1060144968 bose:

 
 If you could do it at all it would have to be something
 like the following.  If it doesn't work then give Walter
 a hard time about it because you should be able to do things
 like this in D.
 
 
 template DefaultComparator(T)
 {
 struct Functions 
 {
 static int compare(const T* a, const T* b) { return compare_logic; }
 }
 }
 
 template TreeT(T,Comparator)
 {
 
 class Tree 
 {
 tree_stuff();
 }
 }
 
 template TreeT(T)
 {
 alias instance TreeT(T,instance DefaultComparator(T)).Tree Tree;
 }
Do any of you wizards comprehend how incomprehensible and ugly that looks to us ordinary programmers?
It's really indescribably ugly.
Aug 06 2003
prev sibling parent "Mike Wynn" <mike.wynn l8night.co.uk> writes:
 Do any of you wizards comprehend how incomprehensible and
 ugly that looks to us ordinary programmers?

 The primary goal of the syntax seems to be to allow the
 existing parser constructs to handle it easily, rather than
 understandability.
and I though I was the only one struggeling with the horrid verbosity of templates even a few aliases seem only to releave the pain slightly. the C++ <> for templates cause major parser headaches I have wondered if without resorting to pascal style begin/end to free {}'s if they could be used instead Vector{int} a; Vector{Array{obj}} b = new Vector{Array{obj}}( 44 ); but D templates are "modules" not just classes or func, it would be good to have template class foo( T ) { } foo(int) etc or foo{int} so the constructor becomes foo{int} f = new foo{int}(44); not foo(int) f = new foo(int)(44); one things that I think should be considered is adding a 'var' or 'my' (like perl) keyword so instead of int a, b =1; use var int a, b = 1; this would reduce the parsers requirement to be able to determine if a statement was a var declare or an actual statment and I don't see it as a great over head in typing. etc.
Aug 07 2003