www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - On the richness of C++

reply Georg Wrede <georg nospam.org> writes:
I read

http://www.nwcpp.org/Downloads/2007/redcode_-_updated.pdf

and upon reading it I got thinking of something else. Those familiar 
with C++ (aren't we all?) probably sometimes come across things that 
somebody has done in C++ that are simply stunning. Things that one would 
have thought would need a new language, or maybe just be impossible to 
implement at all. I know I have. (A lot of Boost stuff is like that, 
originally the STL got me breathless, but there's a lot that's not 
template related, too.)

Is it just paranoia, or is C++ still more flexible and expressive than D?

Are there still things you can do in C++ that are impossible or too 
awkward to do in D?

Of course, I don't mean Obfuscated C(++). While that definitely 
demonstrates the unfathomable agility of the language, I'm only talking 
about serious, non-juvenile stuff.
Apr 10 2008
next sibling parent Jason House <jason.james.house gmail.com> writes:
Georg Wrede Wrote:

 I read
 
 http://www.nwcpp.org/Downloads/2007/redcode_-_updated.pdf
 
 and upon reading it I got thinking of something else. Those familiar 
 with C++ (aren't we all?) probably sometimes come across things that 
 somebody has done in C++ that are simply stunning. Things that one would 
 have thought would need a new language, or maybe just be impossible to 
 implement at all. I know I have. (A lot of Boost stuff is like that, 
 originally the STL got me breathless, but there's a lot that's not 
 template related, too.)
 
 Is it just paranoia, or is C++ still more flexible and expressive than D?
While I don't know how I'd really implement this in C++ or D without third-party libraries, this appears to be nothing more than tuple manipulation. If you can search for a given type in a tuple and delete a type in a tuple, then you can do this in D. I suspect that is not a significant burden for those who practice MP.
 Are there still things you can do in C++ that are impossible or too 
 awkward to do in D?
Great question. Do we allow as much helper code in the background that C++ users use? The paper relies on MPL (on top of TMP). MPL isn't a small little bit of C++ code either...
 Of course, I don't mean Obfuscated C(++). While that definitely 
 demonstrates the unfathomable agility of the language, I'm only talking 
 about serious, non-juvenile stuff.
Apr 10 2008
prev sibling next sibling parent reply Sean Kelly <sean invisibleduck.org> writes:
== Quote from Georg Wrede (georg nospam.org)'s article
 I read
 http://www.nwcpp.org/Downloads/2007/redcode_-_updated.pdf
 and upon reading it I got thinking of something else. Those familiar
 with C++ (aren't we all?) probably sometimes come across things that
 somebody has done in C++ that are simply stunning. Things that one would
 have thought would need a new language, or maybe just be impossible to
 implement at all. I know I have. (A lot of Boost stuff is like that,
 originally the STL got me breathless, but there's a lot that's not
 template related, too.)
 Is it just paranoia, or is C++ still more flexible and expressive than D?
 Are there still things you can do in C++ that are impossible or too
 awkward to do in D?
I think one could argue that the current implementation of mixins is a weak replacement for multiple inheritance, and that this makes certain design patterns a bit less pleasant in D than they would be in C++. Also, the lack of ADL in D can be frustrating at times, though D 2.0's overload groups may address this issue. In fact, it's overload groups and struct ctors that has me wanting to move to D 2.0.
 Of course, I don't mean Obfuscated C(++). While that definitely
 demonstrates the unfathomable agility of the language, I'm only talking
 about serious, non-juvenile stuff.
As far a template metaprogramming is concerned, while a great deal is possible in C++ (as Boost shows), the syntax is such that I don't actually support the idea of using it for anything sufficiently non-trivial. While I feel that metaprogramming is conceptually very straightforward, actually using it to the degree suggested in modern literature tends to render the resulting program incomprehensible and unmaintainable by the vast bulk of C++ programmers. Thus I feel the issue often isn't implementing something fancy so much as making it sufficiently elegant that it's practically usable. Another issue with template metaprogramming is that there is precious little literature on the topic. Andrei's book uses it a great deal, but the only C++ book I know of that actually describes common constructs is "Generative Programming," which few people seem to have read. I'll admit that this was one motivating factor for my covering it in our book on D--I was hoping to make template metaprogramming seem a bit more understandable and at the same time show how much cleaner the D syntax is for this sort of thing. It's perhaps worth mentioning as well that between string mixins and CTFE, D is light years ahead of C++ in terms of metaprogramming. This is one area where it's fairly easy to render code completely impenetrable, but it can be quite elegant if used correctly. And CTFE is a good companion for template metaprogramming in that each have their respective strengths. Sean
Apr 10 2008
parent reply Jason House <jason.james.house gmail.com> writes:
Sean Kelly Wrote:

 == Quote from Georg Wrede (georg nospam.org)'s article
 Is it just paranoia, or is C++ still more flexible and expressive than D?
 Are there still things you can do in C++ that are impossible or too
 awkward to do in D?
I think one could argue that the current implementation of mixins is a weak replacement for multiple inheritance, and that this makes certain design patterns a bit less pleasant in D than they would be in C++. Also, the lack of ADL in D can be frustrating at times, though D 2.0's overload groups may address this issue. In fact, it's overload groups and struct ctors that has me wanting to move to D 2.0.
What's ADL? A quick web search didn't turn up any obvious definitions...
Apr 10 2008
parent Sean Kelly <sean invisibleduck.org> writes:
== Quote from Jason House (jason.james.house gmail.com)'s article
 Sean Kelly Wrote:
 == Quote from Georg Wrede (georg nospam.org)'s article
 Is it just paranoia, or is C++ still more flexible and expressive than D?
 Are there still things you can do in C++ that are impossible or too
 awkward to do in D?
I think one could argue that the current implementation of mixins is a weak replacement for multiple inheritance, and that this makes certain design patterns a bit less pleasant in D than they would be in C++. Also, the lack of ADL in D can be frustrating at times, though D 2.0's overload groups may address this issue. In fact, it's overload groups and struct ctors that has me wanting to move to D 2.0.
What's ADL? A quick web search didn't turn up any obvious definitions...
Argument-dependent lookup--also called Koenig lookup. Sean
Apr 10 2008
prev sibling next sibling parent reply Kevin Bealer <kevinbealer gmail.com> writes:
Georg Wrede Wrote:

 I read
 
 http://www.nwcpp.org/Downloads/2007/redcode_-_updated.pdf
 
 and upon reading it I got thinking of something else. Those familiar 
 with C++ (aren't we all?) probably sometimes come across things that 
 somebody has done in C++ that are simply stunning. Things that one would 
 have thought would need a new language, or maybe just be impossible to 
 implement at all. I know I have. (A lot of Boost stuff is like that, 
 originally the STL got me breathless, but there's a lot that's not 
 template related, too.)
 
 Is it just paranoia, or is C++ still more flexible and expressive than D?
 
 Are there still things you can do in C++ that are impossible or too 
 awkward to do in D?
 
 Of course, I don't mean Obfuscated C(++). While that definitely 
 demonstrates the unfathomable agility of the language, I'm only talking 
 about serious, non-juvenile stuff.
Sometimes. If you want to wrap a small type like int or char in a structure and do really advanced class-based stuff, I think C++ lets you do this and keep both maximum efficiently and maximum flexibility, whereas in D, you need to pick either a class or a struct, and some capabilities drop out with the struct types. In C++ you can inherit a bunch of small (e.g. 4 byte) objects from each other and use template specialization to do compile time "dispatches" on the inheritance hierarchy and so on. D can do some of this but its hard to do it the same way. If you want to do really specific things with memory, C++ lets you do this, but in D classes can only be handled by their object references. You can't do a "placement new" or anything like it with D classes. In C++ you could build classes that automatically allocate themself in a shared memory segment, but in D, probably not. Note that in practice, this is hard to do right and I think is rarely used for much. But I think D's advantages far outweigh these kinds of issues for almost all real programming, and some things that are "in the pipe" like struct constructors or destructors (which one was it?) will provide some of the missing functionality. Another thing, though ... I was amazed that Boost could do things like the Lambda support with _1 _2, etc. Those Boost guys are geniuses. But it worries me that when first seeing it done, I can't even guess how it is possible. It also breaks down in a dozen ways -- if the expressions aren't written exactly right, the wrong things happen at compile versus runtime, binding doesn't happen right, etc. It's hard to know, until the code is running, whether it is doing anything like what you meant it to. It's sort of like a lawnmower that runs on dynamite. Programming is like a chess game -- how much you can accomplish is dependant on how many moves you can see ahead. The C++ syntax to do metaprogramming is very obscure -- this is why people didn't know it existed until after templates were invented. The fact that lambdas are possible is cool. The fact that the space of possible techniques is so opaque is less cool... in C++ you don't know if a thing is possible nearly as easily as in a language like D where the path is better marked, and where there are explicit syntaxes for these things. For example, in C++ I was trying to write a static assert, but there are several ways to do it and some of the syntaxes that used to work (arrays with 0 or even negative size) no longer counted as errors. It took a good hour working out what fails and works in what contexts. And I still only know the answer for one compiler. (I think there's a better version in Imperfect C++ for those interested). In D, the syntax is simpler, and more direct, and more explicit, so you don't need to be a chess master (as often) to figure out whether you can even get from point A to point B, or how to get there, (or why it won't compile...) Kevin
Apr 10 2008
next sibling parent reply Sean Kelly <sean invisibleduck.org> writes:
== Quote from Kevin Bealer (kevinbealer gmail.com)'s article
 If you want to do really specific things with memory, C++ lets you do this, but
 in D classes can only be handled by their object references.  You can't do a
 "placement new" or anything like it with D classes.  In C++ you could build
 classes that automatically allocate themself in a shared memory segment, but
 in D, probably not.  Note that in practice, this is hard to do right and I
think is
 rarely used for much.
I'd personally like for "placement new" to be supported by the language. I've considered adding a new(void*) method to Object for this purpose in Tango, but haven't experimented enough to find out if this would cause any problems. One I can think of is that certain hierarchies seem like they could cause this to throw: class Object { void* new( size_t s, void* p ) { return p; } } class C { void* new( size_t s, Allocator a ) { return a.alloc( s ); } } class D { void* new( size_t s, Allocator a ) { printf( "hello!\n" ); return super.new( s, a ); } void* pos = ...; auto var = new( pos ) D; With the vtbl checking in D, I think the above call will throw a "not implemented" message because D overrides one inherited "new" routine but not the "placement new" routine inherited from Object. In fact, this has me wondering about the practicality of this sort of checking at all. It seems a fairly straightforward design for the language to consider broken. Sean
Apr 10 2008
next sibling parent reply Kevin Bealer <kevinbealer gmail.com> writes:
Sean Kelly Wrote:

 == Quote from Kevin Bealer (kevinbealer gmail.com)'s article
 If you want to do really specific things with memory, C++ lets you do this, but
 in D classes can only be handled by their object references.  You can't do a
 "placement new" or anything like it with D classes.  In C++ you could build
 classes that automatically allocate themself in a shared memory segment, but
 in D, probably not.  Note that in practice, this is hard to do right and I
think is
 rarely used for much.
I'd personally like for "placement new" to be supported by the language. I've considered adding a new(void*) method to Object for this purpose in Tango, but haven't experimented enough to find out if this would cause any problems.
... I can think of these reasons off hand why (C++) folks do placement new. 1. Allocate lots of class objects at once to reduce allocations. 2. Allocate-on-stack for objects to avoid allocation altogether. 3. Group classes together for memory locality. 4. Tricks like surrounding objects with DEADBEEF for memory corruption detection, or adding next or left/right pointers to objects. Out of curiosity, what motivates your desire for placement new? Kevin
Apr 10 2008
next sibling parent Robert Fraser <fraserofthenight gmail.com> writes:
Kevin Bealer wrote:
 Sean Kelly Wrote:
 
 == Quote from Kevin Bealer (kevinbealer gmail.com)'s article
 If you want to do really specific things with memory, C++ lets you do this, but
 in D classes can only be handled by their object references.  You can't do a
 "placement new" or anything like it with D classes.  In C++ you could build
 classes that automatically allocate themself in a shared memory segment, but
 in D, probably not.  Note that in practice, this is hard to do right and I
think is
 rarely used for much.
I'd personally like for "placement new" to be supported by the language. I've considered adding a new(void*) method to Object for this purpose in Tango, but haven't experimented enough to find out if this would cause any problems.
... I can think of these reasons off hand why (C++) folks do placement new. 1. Allocate lots of class objects at once to reduce allocations. 2. Allocate-on-stack for objects to avoid allocation altogether. 3. Group classes together for memory locality. 4. Tricks like surrounding objects with DEADBEEF for memory corruption detection, or adding next or left/right pointers to objects. Out of curiosity, what motivates your desire for placement new? Kevin
(2) is solved in D by using scope classes. But the others still remain vaild reasons why a placement new is useful.
Apr 10 2008
prev sibling parent Sean Kelly <sean invisibleduck.org> writes:
== Quote from Kevin Bealer (kevinbealer gmail.com)'s article
 Out of curiosity, what motivates your desire for placement new?
Constructing D objects in shared memory. That's also an underlying reason why I added a way to override object monitors in Tango. Sean
Apr 11 2008
prev sibling next sibling parent reply Frits van Bommel <fvbommel REMwOVExCAPSs.nl> writes:
Sean Kelly wrote:
 I'd personally like for "placement new" to be supported by the language.  I've
 considered adding a new(void*) method to Object for this purpose in Tango,
 but haven't experimented enough to find out if this would cause any problems.
[snip]
 
     class Object {
         void* new( size_t s, void* p ) {
             return p;
         }
     }
Might I suggest that if you ever again get the urge to add placement new, you consider adding --- void* new( size_t s, void[] arr ) { assert(s <= arr.length); return arr.ptr; } --- instead?
Apr 11 2008
parent Frits van Bommel <fvbommel REMwOVExCAPSs.nl> writes:
Frits van Bommel wrote:
 Sean Kelly wrote:
[snip]
     class Object {
         void* new( size_t s, void* p ) {
             return p;
         }
     }
Might I suggest that if you ever again get the urge to add placement new, you consider adding --- void* new( size_t s, void[] arr ) { assert(s <= arr.length); return arr.ptr; } --- instead?
Oh, and after reading the spec: the 'void*' in front of 'new' shouldn't be there. Like with constructors, the return type is implicit.
Apr 11 2008
prev sibling parent reply Frits van Bommel <fvbommel REMwOVExCAPSs.nl> writes:
Sean Kelly wrote:
 With the vtbl checking in D, I think the above call will throw a "not
implemented"
 message because D overrides one inherited "new" routine but not the "placement
 new" routine inherited from Object.  In fact, this has me wondering about the
 practicality of this sort of checking at all.  It seems a fairly
straightforward
 design for the language to consider broken.
Actually, that doesn't apply to class allocators. Since no instance exists yet, they don't do the vtable lookup; they're implicitly static. And that means calling inherited class allocators, at least from outside the class itself, is an error if a new one is defined. Also, I'm not sure if you can call an inherited allocator with 'super' as you're trying to do in class D.
Apr 11 2008
parent reply Sean Kelly <sean invisibleduck.org> writes:
== Quote from Frits van Bommel (fvbommel REMwOVExCAPSs.nl)'s article
 Sean Kelly wrote:
 With the vtbl checking in D, I think the above call will throw a "not
implemented"
 message because D overrides one inherited "new" routine but not the "placement
 new" routine inherited from Object.  In fact, this has me wondering about the
 practicality of this sort of checking at all.  It seems a fairly
straightforward
 design for the language to consider broken.
Actually, that doesn't apply to class allocators. Since no instance exists yet, they don't do the vtable lookup; they're implicitly static. And that means calling inherited class allocators, at least from outside the class itself, is an error if a new one is defined.
That's a slightly odd rule. I'd think that explicitly calling obj.new() would be fine since doing so shouldn't mutate the instance. Or did I misunderstand?
 Also, I'm not sure if you can call an inherited allocator with 'super'
 as you're trying to do in class D.
Really? Strange. Hm... well upon further reflection, I think this may be a special case for methods in Object, since one could argue that anyone who only wants to override a subset of overloads should add empty forwarding overloads (ie. that call super) for the remainder, for clarity. But the lack of compile-time checking still stinks... I'm still not sure it prevents more bugs than it creates. Sean
Apr 11 2008
parent reply Sean Kelly <sean invisibleduck.org> writes:
== Quote from Sean Kelly (sean invisibleduck.org)'s article
 == Quote from Frits van Bommel (fvbommel REMwOVExCAPSs.nl)'s article
 Sean Kelly wrote:
 With the vtbl checking in D, I think the above call will throw a "not
implemented"
 message because D overrides one inherited "new" routine but not the "placement
 new" routine inherited from Object.  In fact, this has me wondering about the
 practicality of this sort of checking at all.  It seems a fairly
straightforward
 design for the language to consider broken.
Actually, that doesn't apply to class allocators. Since no instance exists yet, they don't do the vtable lookup; they're implicitly static. And that means calling inherited class allocators, at least from outside the class itself, is an error if a new one is defined.
That's a slightly odd rule. I'd think that explicitly calling obj.new() would be fine since doing so shouldn't mutate the instance. Or did I misunderstand?
 Also, I'm not sure if you can call an inherited allocator with 'super'
 as you're trying to do in class D.
Really? Strange. Hm... well upon further reflection, I think this may be a special case for methods in Object, since one could argue that anyone who only wants to override a subset of overloads should add empty forwarding overloads (ie. that call super) for the remainder, for clarity. But the lack of compile-time checking still stinks... I'm still not sure it prevents more bugs than it creates.
Bah... forget everything I said. You're right of course. Someday I'll learn never to post when tired. It's just such a difficult rule to remember at the appropriate times :-) So for the record. I do think the overload checking is a good idea--it just needs to be clearly documented somewhere (if it isn't already). And the 'super' thing makes total sense--there's no instance so 'super' isn't technically valid. Sean
Apr 11 2008
parent reply Robert Fraser <fraserofthenight gmail.com> writes:
Sean Kelly wrote:
 So for the record.  I do think the overload checking is a good idea--it just
needs
 to be clearly documented somewhere (if it isn't already).  And the 'super'
thing
 makes total sense--there's no instance so 'super' isn't technically valid.
Aren't "super" calls bound at compile-time?
Apr 11 2008
parent Sean Kelly <sean invisibleduck.org> writes:
== Quote from Robert Fraser (fraserofthenight gmail.com)'s article
 Sean Kelly wrote:
 So for the record.  I do think the overload checking is a good idea--it just
needs
 to be clearly documented somewhere (if it isn't already).  And the 'super'
thing
 makes total sense--there's no instance so 'super' isn't technically valid.
Aren't "super" calls bound at compile-time?
My guess would be that a "super" call rebinds to the superclass' vtbl. I don't think it actually does a static lookup and direct function call if that's what you're suggesting, but it does seem technically possible. In any case, using "super" here may actually work in this case since the "new" method is effectively static, but it doesn't seem any more advisable to use it than you would "this" in the same situation. It's just bad style, if nothing else. Sean
Apr 11 2008
prev sibling parent reply Walter Bright <newshound1 digitalmars.com> writes:
Kevin Bealer wrote:
 I was amazed that Boost could do things like the Lambda support with _1 _2,
etc.
 Those Boost guys are geniuses.
I agree, they are geniuses. But that's really what is wrong with C++, you shouldn't have to be a genius to get advanced things done.
Apr 11 2008
parent reply Edward Diener <eddielee_no_spam_here tropicsoft.com> writes:
Walter Bright wrote:
 Kevin Bealer wrote:
 I was amazed that Boost could do things like the Lambda support with 
 _1 _2, etc.
 Those Boost guys are geniuses.
I agree, they are geniuses. But that's really what is wrong with C++, you shouldn't have to be a genius to get advanced things done.
Are D's templates a complete replacement in functionality for Boost's MPL ? If so could you write an article on your web site about the how's and why's of that ? I am still trying to understand D's templates based on the sparse documentation of them. Remember that part of the difficult for the Boost developer is also supporting many non-conforming C++ compilers, so part of the genius of what they are doing is manipulating around compilers that do not deal with C++ templates correctly ( perhaps because the details of the C++ template system are so abstruse and difficult to understand and implement).
Apr 12 2008
next sibling parent Sean Kelly <sean invisibleduck.org> writes:
== Quote from Edward Diener (eddielee_no_spam_here tropicsoft.com)'s article
 Walter Bright wrote:
 Kevin Bealer wrote:
 I was amazed that Boost could do things like the Lambda support with
 _1 _2, etc.
 Those Boost guys are geniuses.
I agree, they are geniuses. But that's really what is wrong with C++, you shouldn't have to be a genius to get advanced things done.
Are D's templates a complete replacement in functionality for Boost's MPL ? If so could you write an article on your web site about the how's and why's of that ? I am still trying to understand D's templates based on the sparse documentation of them.
I'm not sure if it helps, but the D book that I and some of the other Tango folks wrote has a chapter on templates. I think it's probably the most extensive "how to" document available right now. It's not free, but I believe the e-book version is only like $13.
 Remember that part of the difficult for the Boost developer is also
 supporting many non-conforming C++ compilers, so part of the genius of
 what they are doing is manipulating around compilers that do not deal
 with C++ templates correctly ( perhaps because the details of the C++
 template system are so abstruse and difficult to understand and implement).
Exactly. Sean
Apr 12 2008
prev sibling parent reply Walter Bright <newshound1 digitalmars.com> writes:
Edward Diener wrote:
 Walter Bright wrote:
 Kevin Bealer wrote:
 I was amazed that Boost could do things like the Lambda support with 
 _1 _2, etc.
 Those Boost guys are geniuses.
I agree, they are geniuses. But that's really what is wrong with C++, you shouldn't have to be a genius to get advanced things done.
Are D's templates a complete replacement in functionality for Boost's MPL ? If so could you write an article on your web site about the how's and why's of that ? I am still trying to understand D's templates based on the sparse documentation of them.
I don't really understand Boost MPL, but D's template system is considerably more powerful than C++'s. I agree that more documentation is needed, but one can easily write a book about it.
 Remember that part of the difficult for the Boost developer is also 
 supporting many non-conforming C++ compilers, so part of the genius of 
 what they are doing is manipulating around compilers that do not deal 
 with C++ templates correctly ( perhaps because the details of the C++ 
 template system are so abstruse and difficult to understand and implement).
It's amazing even not considering compiler bug workarounds. And yes, a large reason for the compiler bugs is because it is so hard to understand how it is supposed to work.
Apr 12 2008
next sibling parent reply Edward Diener <eddielee_no_spam_here tropicsoft.com> writes:
Walter Bright wrote:
 Edward Diener wrote:
 Walter Bright wrote:
 Kevin Bealer wrote:
 I was amazed that Boost could do things like the Lambda support with 
 _1 _2, etc.
 Those Boost guys are geniuses.
I agree, they are geniuses. But that's really what is wrong with C++, you shouldn't have to be a genius to get advanced things done.
Are D's templates a complete replacement in functionality for Boost's MPL ? If so could you write an article on your web site about the how's and why's of that ? I am still trying to understand D's templates based on the sparse documentation of them.
I don't really understand Boost MPL, but D's template system is considerably more powerful than C++'s.
I do not know the MPL either although I understand the general concept. It is a C++ template metaprogramming library for manipulating types at compile time so that the final result of the body of a template deals in whatever types the template metaprogramming needs to generalize for his programming task. I agree that what I currently understand of D templates looks clearer than the template system in C++ but I am not knowledgable enough to know whether it is "better", or easier to use in doing the sorts of things which Boost programmers accomplish.
 I agree that more documentation 
 is needed, but one can easily write a book about it.
The question is: has anyone tackled in D some of the template metaprogramming tasks which various Boost programmers have accomplished with C++ ? I am trying to get a feel for how different, or how much easier ( or perhaps harder ) it would be to do Boost things like Spirit ( lex/yacc-like DSEL ), function ( universal callable ), bind and/or lambda ( function object creation ), shared_ptr ( sharable smart pointer, obviously for RAII in D because of GC ), signals ( generalized multicast events ), multi_index ( multiple index containers ), regex and/or xpressive ( regular expressions ), tokenizer ( generalized tokening of strings ), date_time ( date/time and time intervals ) and many others ( the above are just my favorites but I have hardly explored/used all of them ) which C++ programmers find very useful. All of these libraries depend on template metaprogramming in C++. Can their equivalents just as easily be implemented and have any of them been done already ? I have not looked at the D libraries, phobos and tango I believe they are called, so maybe I am way off base comparing the Boost libraries to what may already be in D. But I am trying to get an idea if D is capable of doing these Boost things just as easily or easier.
Apr 12 2008
next sibling parent reply Georg Wrede <georg nospam.org> writes:
Edward Diener wrote:
 Walter Bright wrote:
 
 Edward Diener wrote:

 Walter Bright wrote:

 Kevin Bealer wrote:

 I was amazed that Boost could do things like the Lambda support 
 with _1 _2, etc.
 Those Boost guys are geniuses.
I agree, they are geniuses. But that's really what is wrong with C++, you shouldn't have to be a genius to get advanced things done.
Are D's templates a complete replacement in functionality for Boost's MPL ? If so could you write an article on your web site about the how's and why's of that ? I am still trying to understand D's templates based on the sparse documentation of them.
I don't really understand Boost MPL, but D's template system is considerably more powerful than C++'s.
I do not know the MPL either although I understand the general concept. It is a C++ template metaprogramming library for manipulating types at compile time so that the final result of the body of a template deals in whatever types the template metaprogramming needs to generalize for his programming task. I agree that what I currently understand of D templates looks clearer than the template system in C++ but I am not knowledgable enough to know whether it is "better", or easier to use in doing the sorts of things which Boost programmers accomplish.
 I agree that more documentation is needed, but one can easily write a 
 book about it.
The question is: has anyone tackled in D some of the template metaprogramming tasks which various Boost programmers have accomplished with C++ ? I am trying to get a feel for how different, or how much easier ( or perhaps harder ) it would be to do Boost things like Spirit ( lex/yacc-like DSEL ), function ( universal callable ), bind and/or lambda ( function object creation ), shared_ptr ( sharable smart pointer, obviously for RAII in D because of GC ), signals ( generalized multicast events ), multi_index ( multiple index containers ), regex and/or xpressive ( regular expressions ), tokenizer ( generalized tokening of strings ), date_time ( date/time and time intervals ) and many others ( the above are just my favorites but I have hardly explored/used all of them ) which C++ programmers find very useful. All of these libraries depend on template metaprogramming in C++. Can their equivalents just as easily be implemented and have any of them been done already ?
Now the above is approaching the idea of this thread.
 I have not looked at the D libraries, phobos and tango I believe they 
 are called, so maybe I am way off base comparing the Boost libraries to 
 what may already be in D. But I am trying to get an idea if D is capable 
 of doing these Boost things just as easily or easier.
Yes! And I think those are things that very may, who don't regularly write in this NG, really wonder about with D.
Apr 13 2008
parent reply Edward Diener <eddielee_no_spam_here tropicsoft.com> writes:
Georg Wrede wrote:
 Edward Diener wrote:
 Walter Bright wrote:

 Edward Diener wrote:

 Walter Bright wrote:

 Kevin Bealer wrote:

 I was amazed that Boost could do things like the Lambda support 
 with _1 _2, etc.
 Those Boost guys are geniuses.
I agree, they are geniuses. But that's really what is wrong with C++, you shouldn't have to be a genius to get advanced things done.
Are D's templates a complete replacement in functionality for Boost's MPL ? If so could you write an article on your web site about the how's and why's of that ? I am still trying to understand D's templates based on the sparse documentation of them.
I don't really understand Boost MPL, but D's template system is considerably more powerful than C++'s.
I do not know the MPL either although I understand the general concept. It is a C++ template metaprogramming library for manipulating types at compile time so that the final result of the body of a template deals in whatever types the template metaprogramming needs to generalize for his programming task. I agree that what I currently understand of D templates looks clearer than the template system in C++ but I am not knowledgable enough to know whether it is "better", or easier to use in doing the sorts of things which Boost programmers accomplish.
 I agree that more documentation is needed, but one can easily write a 
 book about it.
The question is: has anyone tackled in D some of the template metaprogramming tasks which various Boost programmers have accomplished with C++ ? I am trying to get a feel for how different, or how much easier ( or perhaps harder ) it would be to do Boost things like Spirit ( lex/yacc-like DSEL ), function ( universal callable ), bind and/or lambda ( function object creation ), shared_ptr ( sharable smart pointer, obviously for RAII in D because of GC ), signals ( generalized multicast events ), multi_index ( multiple index containers ), regex and/or xpressive ( regular expressions ), tokenizer ( generalized tokening of strings ), date_time ( date/time and time intervals ) and many others ( the above are just my favorites but I have hardly explored/used all of them ) which C++ programmers find very useful. All of these libraries depend on template metaprogramming in C++. Can their equivalents just as easily be implemented and have any of them been done already ?
Now the above is approaching the idea of this thread.
In Boost there is an entire metaprogramming paradigm based on a set of conventions regarding C++ templates and types, as implemented by the Boost MPL. This is despite the fact that C++ template syntax is much more abstruse than D's templates. So I was merely wondering if there is anything equivalent in D which can manipulate templates the way that the Boost MPL can. I agree that D's templates appear much easier to use but whether or not they are richer in functionality than C++ templates is something I do not know, but would love to find out about. But that would mean a comparison between what D can do with its templates as opposed to what the Boost MPL can do.
 
 I have not looked at the D libraries, phobos and tango I believe they 
 are called, so maybe I am way off base comparing the Boost libraries 
 to what may already be in D. But I am trying to get an idea if D is 
 capable of doing these Boost things just as easily or easier.
Yes! And I think those are things that very may, who don't regularly write in this NG, really wonder about with D.
The template syntax is clearer, but I don't know if it is better, and/or why. I am a big advocate of clarity in computer languages but not if there is any loss of functionality. I do not believe that clarity should ever be sacrificed for needed functionality. That is one reason I still Taking away functionality for clarity is never the way to go, but adding clarity while keeping, or improving the same functionality, as D has done in mostr cases, is admirable. However in some areas D seems to have given away functionality for clarity, or some holy grail which few understand, as in the const debacle. I am hoping Walter will address this issue of template functionality as opposed to syntax, between C++ and D, extensively sometime in the future, hopefully in a technically neutral way ( he tends to be biased toward D fro some odd reason <g> ).
Apr 13 2008
parent reply Bill Baxter <dnewsgroup billbaxter.com> writes:
Edward Diener wrote:
 Georg Wrede wrote:
 Edward Diener wrote:
 Walter Bright wrote:

 Edward Diener wrote:

 Walter Bright wrote:

 Kevin Bealer wrote:

 I was amazed that Boost could do things like the Lambda support 
 with _1 _2, etc.
 Those Boost guys are geniuses.
I agree, they are geniuses. But that's really what is wrong with C++, you shouldn't have to be a genius to get advanced things done.
Are D's templates a complete replacement in functionality for Boost's MPL ? If so could you write an article on your web site about the how's and why's of that ? I am still trying to understand D's templates based on the sparse documentation of them.
I don't really understand Boost MPL, but D's template system is considerably more powerful than C++'s.
I do not know the MPL either although I understand the general concept. It is a C++ template metaprogramming library for manipulating types at compile time so that the final result of the body of a template deals in whatever types the template metaprogramming needs to generalize for his programming task. I agree that what I currently understand of D templates looks clearer than the template system in C++ but I am not knowledgable enough to know whether it is "better", or easier to use in doing the sorts of things which Boost programmers accomplish.
 I agree that more documentation is needed, but one can easily write 
 a book about it.
The question is: has anyone tackled in D some of the template metaprogramming tasks which various Boost programmers have accomplished with C++ ? I am trying to get a feel for how different, or how much easier ( or perhaps harder ) it would be to do Boost things like Spirit ( lex/yacc-like DSEL ), function ( universal callable ), bind and/or lambda ( function object creation ), shared_ptr ( sharable smart pointer, obviously for RAII in D because of GC ), signals ( generalized multicast events ), multi_index ( multiple index containers ), regex and/or xpressive ( regular expressions ), tokenizer ( generalized tokening of strings ), date_time ( date/time and time intervals ) and many others ( the above are just my favorites but I have hardly explored/used all of them ) which C++ programmers find very useful. All of these libraries depend on template metaprogramming in C++. Can their equivalents just as easily be implemented and have any of them been done already ?
Now the above is approaching the idea of this thread.
In Boost there is an entire metaprogramming paradigm based on a set of conventions regarding C++ templates and types, as implemented by the Boost MPL. This is despite the fact that C++ template syntax is much more abstruse than D's templates. So I was merely wondering if there is anything equivalent in D which can manipulate templates the way that the Boost MPL can. I agree that D's templates appear much easier to use but whether or not they are richer in functionality than C++ templates is something I do not know, but would love to find out about. But that would mean a comparison between what D can do with its templates as opposed to what the Boost MPL can do.
 I have not looked at the D libraries, phobos and tango I believe they 
 are called, so maybe I am way off base comparing the Boost libraries 
 to what may already be in D. But I am trying to get an idea if D is 
 capable of doing these Boost things just as easily or easier.
Yes! And I think those are things that very may, who don't regularly write in this NG, really wonder about with D.
The template syntax is clearer, but I don't know if it is better, and/or why. I am a big advocate of clarity in computer languages but not if there is any loss of functionality. I do not believe that clarity should ever be sacrificed for needed functionality. That is one reason I still Taking away functionality for clarity is never the way to go, but adding clarity while keeping, or improving the same functionality, as D has done in mostr cases, is admirable. However in some areas D seems to have given away functionality for clarity, or some holy grail which few understand, as in the const debacle. I am hoping Walter will address this issue of template functionality as opposed to syntax, between C++ and D, extensively sometime in the future, hopefully in a technically neutral way ( he tends to be biased toward D fro some odd reason <g> ).
It would be interesting to see what it takes to reproduce MPL in D. But here's a quickie for you, to implement a "type sequence" like mentioned here [http://www.boost.org/doc/libs/1_35_0/libs/mpl/doc/tutorial/represent ng-dimensions.html] the code looks basically like this: template boost_mpl_vector(T...) { alias T boost_mpl_vector; } Then you can do like the first example on that page: alias boost_mpl_vector!(char, short, int, long) signed_types; The next one, the int_<N> template is probably just this in D: template int_(int N) { const value = N; } Or maybe it would be struct int_(int N) { static const value = N; } Then the "vector_c" integral sequence wrapper starts to get interesting, but is probably something like this: template vector_c(T, Vals...) { alias ConstList!(int, Vals) vector_c; } ... plus one recursively defined template ConstList, which would probably be about 5-10 lines of code. Sorry, don't have time to work it through right now, but maybe someone else can pick up from there. :-) --bb
Apr 13 2008
parent reply Bill Baxter <dnewsgroup billbaxter.com> writes:
Bill Baxter wrote:
 Edward Diener wrote:
 Georg Wrede wrote:
 Edward Diener wrote:
 Walter Bright wrote:

 Edward Diener wrote:

 Walter Bright wrote:

 Kevin Bealer wrote:

 I was amazed that Boost could do things like the Lambda support 
 with _1 _2, etc.
 Those Boost guys are geniuses.
I agree, they are geniuses. But that's really what is wrong with C++, you shouldn't have to be a genius to get advanced things done.
Are D's templates a complete replacement in functionality for Boost's MPL ? If so could you write an article on your web site about the how's and why's of that ? I am still trying to understand D's templates based on the sparse documentation of them.
I don't really understand Boost MPL, but D's template system is considerably more powerful than C++'s.
I do not know the MPL either although I understand the general concept. It is a C++ template metaprogramming library for manipulating types at compile time so that the final result of the body of a template deals in whatever types the template metaprogramming needs to generalize for his programming task. I agree that what I currently understand of D templates looks clearer than the template system in C++ but I am not knowledgable enough to know whether it is "better", or easier to use in doing the sorts of things which Boost programmers accomplish.
 I agree that more documentation is needed, but one can easily write 
 a book about it.
The question is: has anyone tackled in D some of the template metaprogramming tasks which various Boost programmers have accomplished with C++ ? I am trying to get a feel for how different, or how much easier ( or perhaps harder ) it would be to do Boost things like Spirit ( lex/yacc-like DSEL ), function ( universal callable ), bind and/or lambda ( function object creation ), shared_ptr ( sharable smart pointer, obviously for RAII in D because of GC ), signals ( generalized multicast events ), multi_index ( multiple index containers ), regex and/or xpressive ( regular expressions ), tokenizer ( generalized tokening of strings ), date_time ( date/time and time intervals ) and many others ( the above are just my favorites but I have hardly explored/used all of them ) which C++ programmers find very useful. All of these libraries depend on template metaprogramming in C++. Can their equivalents just as easily be implemented and have any of them been done already ?
Now the above is approaching the idea of this thread.
In Boost there is an entire metaprogramming paradigm based on a set of conventions regarding C++ templates and types, as implemented by the Boost MPL. This is despite the fact that C++ template syntax is much more abstruse than D's templates. So I was merely wondering if there is anything equivalent in D which can manipulate templates the way that the Boost MPL can. I agree that D's templates appear much easier to use but whether or not they are richer in functionality than C++ templates is something I do not know, but would love to find out about. But that would mean a comparison between what D can do with its templates as opposed to what the Boost MPL can do.
 I have not looked at the D libraries, phobos and tango I believe 
 they are called, so maybe I am way off base comparing the Boost 
 libraries to what may already be in D. But I am trying to get an 
 idea if D is capable of doing these Boost things just as easily or 
 easier.
Yes! And I think those are things that very may, who don't regularly write in this NG, really wonder about with D.
The template syntax is clearer, but I don't know if it is better, and/or why. I am a big advocate of clarity in computer languages but not if there is any loss of functionality. I do not believe that clarity should ever be sacrificed for needed functionality. That is not improvements. Taking away functionality for clarity is never the way to go, but adding clarity while keeping, or improving the same functionality, as D has done in mostr cases, is admirable. However in some areas D seems to have given away functionality for clarity, or some holy grail which few understand, as in the const debacle. I am hoping Walter will address this issue of template functionality as opposed to syntax, between C++ and D, extensively sometime in the future, hopefully in a technically neutral way ( he tends to be biased toward D fro some odd reason <g> ).
It would be interesting to see what it takes to reproduce MPL in D. But here's a quickie for you, to implement a "type sequence" like mentioned here [http://www.boost.org/doc/libs/1_35_0/libs/mpl/doc/tutorial/represent ng-dimensions.html] the code looks basically like this: template boost_mpl_vector(T...) { alias T boost_mpl_vector; } Then you can do like the first example on that page: alias boost_mpl_vector!(char, short, int, long) signed_types; The next one, the int_<N> template is probably just this in D: template int_(int N) { const value = N; } Or maybe it would be struct int_(int N) { static const value = N; } Then the "vector_c" integral sequence wrapper starts to get interesting, but is probably something like this: template vector_c(T, Vals...) { alias ConstList!(int, Vals) vector_c; }
The ConstList will look something like template ConstList!(T, Vals...) { static if (Vals.length == 0) { alias Tuple!() ConstList; } else { alias Tuple!(int_!(Vals[0]), ConstList!(T, Vals[1..$])) ConstList; } } Except it would have to be a little more complicated to make the transition from the type T to int_ or long_ or whetever the actual constant type was. But that is also pretty easy with static if: template ConstType(T) { static if (is(T==int)) { alias int_ ConstType; } static if (is(T==long)) { alias long_ ConstType; } static if (is(T==byte)) { alias byte_ ConstType; } ... etc } There may be a radically better way to do that whole thing, though, since Tuple!() can already accept constants in addition to types. The int_ long_ etc helper types might not be necessary at all. You might want to check out std.traits, std.metastrings, std.typecons and std.typetuple from Phobos for some template metacode functions. --bb
Apr 13 2008
parent reply Edward Diener <eddielee_no_spam_here tropicsoft.com> writes:
Bill Baxter wrote:
 Bill Baxter wrote:
 Edward Diener wrote:
 Georg Wrede wrote:
 Edward Diener wrote:
 Walter Bright wrote:

 Edward Diener wrote:

 Walter Bright wrote:

 Kevin Bealer wrote:

 I was amazed that Boost could do things like the Lambda support 
 with _1 _2, etc.
 Those Boost guys are geniuses.
I agree, they are geniuses. But that's really what is wrong with C++, you shouldn't have to be a genius to get advanced things done.
Are D's templates a complete replacement in functionality for Boost's MPL ? If so could you write an article on your web site about the how's and why's of that ? I am still trying to understand D's templates based on the sparse documentation of them.
I don't really understand Boost MPL, but D's template system is considerably more powerful than C++'s.
I do not know the MPL either although I understand the general concept. It is a C++ template metaprogramming library for manipulating types at compile time so that the final result of the body of a template deals in whatever types the template metaprogramming needs to generalize for his programming task. I agree that what I currently understand of D templates looks clearer than the template system in C++ but I am not knowledgable enough to know whether it is "better", or easier to use in doing the sorts of things which Boost programmers accomplish.
 I agree that more documentation is needed, but one can easily 
 write a book about it.
The question is: has anyone tackled in D some of the template metaprogramming tasks which various Boost programmers have accomplished with C++ ? I am trying to get a feel for how different, or how much easier ( or perhaps harder ) it would be to do Boost things like Spirit ( lex/yacc-like DSEL ), function ( universal callable ), bind and/or lambda ( function object creation ), shared_ptr ( sharable smart pointer, obviously for RAII in D because of GC ), signals ( generalized multicast events ), multi_index ( multiple index containers ), regex and/or xpressive ( regular expressions ), tokenizer ( generalized tokening of strings ), date_time ( date/time and time intervals ) and many others ( the above are just my favorites but I have hardly explored/used all of them ) which C++ programmers find very useful. All of these libraries depend on template metaprogramming in C++. Can their equivalents just as easily be implemented and have any of them been done already ?
Now the above is approaching the idea of this thread.
In Boost there is an entire metaprogramming paradigm based on a set of conventions regarding C++ templates and types, as implemented by the Boost MPL. This is despite the fact that C++ template syntax is much more abstruse than D's templates. So I was merely wondering if there is anything equivalent in D which can manipulate templates the way that the Boost MPL can. I agree that D's templates appear much easier to use but whether or not they are richer in functionality than C++ templates is something I do not know, but would love to find out about. But that would mean a comparison between what D can do with its templates as opposed to what the Boost MPL can do.
 I have not looked at the D libraries, phobos and tango I believe 
 they are called, so maybe I am way off base comparing the Boost 
 libraries to what may already be in D. But I am trying to get an 
 idea if D is capable of doing these Boost things just as easily or 
 easier.
Yes! And I think those are things that very may, who don't regularly write in this NG, really wonder about with D.
The template syntax is clearer, but I don't know if it is better, and/or why. I am a big advocate of clarity in computer languages but not if there is any loss of functionality. I do not believe that clarity should ever be sacrificed for needed functionality. That is C++, not improvements. Taking away functionality for clarity is never the way to go, but adding clarity while keeping, or improving the same functionality, as D has done in mostr cases, is admirable. However in some areas D seems to have given away functionality for clarity, or some holy grail which few understand, as in the const debacle. I am hoping Walter will address this issue of template functionality as opposed to syntax, between C++ and D, extensively sometime in the future, hopefully in a technically neutral way ( he tends to be biased toward D fro some odd reason <g> ).
It would be interesting to see what it takes to reproduce MPL in D. But here's a quickie for you, to implement a "type sequence" like mentioned here [http://www.boost.org/doc/libs/1_35_0/libs/mpl/doc/tutorial/represent ng-dimensions.html] the code looks basically like this: template boost_mpl_vector(T...) { alias T boost_mpl_vector; } Then you can do like the first example on that page: alias boost_mpl_vector!(char, short, int, long) signed_types; The next one, the int_<N> template is probably just this in D: template int_(int N) { const value = N; } Or maybe it would be struct int_(int N) { static const value = N; } Then the "vector_c" integral sequence wrapper starts to get interesting, but is probably something like this: template vector_c(T, Vals...) { alias ConstList!(int, Vals) vector_c; }
The ConstList will look something like template ConstList!(T, Vals...) { static if (Vals.length == 0) { alias Tuple!() ConstList; } else { alias Tuple!(int_!(Vals[0]), ConstList!(T, Vals[1..$])) ConstList; } } Except it would have to be a little more complicated to make the transition from the type T to int_ or long_ or whetever the actual constant type was. But that is also pretty easy with static if: template ConstType(T) { static if (is(T==int)) { alias int_ ConstType; } static if (is(T==long)) { alias long_ ConstType; } static if (is(T==byte)) { alias byte_ ConstType; } ... etc } There may be a radically better way to do that whole thing, though, since Tuple!() can already accept constants in addition to types. The int_ long_ etc helper types might not be necessary at all. You might want to check out std.traits, std.metastrings, std.typecons and std.typetuple from Phobos for some template metacode functions.
I will look into the D libraries more, especially the ones you mention. I am just coming to grips with D's templates and have also ordered a book on D which had the somewhat misleading title of dealing only with Phobos, whereas it seems to deal with the D language itself pretty extensively also. D has some really nice features but it really needs much better language documentation to attract programmers, especially C++ programmers. I am extremely good in C++ and if I have had many, many struggles trying to understand D from the specification. Since I can imagine what a less knowledgable programmer must have to go through trying to understand D for the first time, I can understand why someone else might give up based only on the documentation. Thanks for the examples above. I do realize that D has some built-in features which enable template manipulation which Boost MPL has to emulate through some very clever C++ template metaprogramming. In particular, as you have shown above, D has the tuple concept, the static if...else, and also something I like quite a bit, which is that there is no necessity for a base template upon which specializations are built but that each template can be defined with its own specializations. That last feature makes D templates really much easier to write. In other words it seems as if D should be able to do some of the Boost libraries, which makes C++ so pleasurable to use in general despite the difficulty of dealing with C++ templates, fairly easily. At the same time most of the Boost libraries are tremendously useful. I will look in the Phobos library for their equivalents to see if D has some of the same abilities in its library.
Apr 14 2008
next sibling parent reply Bill Baxter <dnewsgroup billbaxter.com> writes:
Edward Diener wrote:

 D has some really nice features but it really needs much better language 
 documentation to attract programmers, especially C++ programmers. 
Hah, I think the same thing every time I'm forced to try to use a boost library. :-) Like just today when I had to go look at Boost::MPL to see what it was all about.
 In other words it seems as if D should be able to do some of the Boost 
 libraries, which makes C++ so pleasurable to use in general despite the 
 difficulty of dealing with C++ templates, fairly easily. At the same 
 time most of the Boost libraries are tremendously useful. I will look in 
 the Phobos library for their equivalents to see if D has some of the 
 same abilities in its library.
The book with the misleading title is about Tango, actually. Maybe you could tackle porting whatever you find useful about Boost::MPL to D as a first project? :-) I'm sure many here would be happy to help. (And would also be interested to find out what people find useful about Boost::MPL -- my one experience trying to use Boost::lambda sent me screaming back to good old for loops.) --bb
Apr 14 2008
next sibling parent Edward Diener <eddielee_no_spam_here tropicsoft.com> writes:
Bill Baxter wrote:
 Edward Diener wrote:
 
 D has some really nice features but it really needs much better 
 language documentation to attract programmers, especially C++ 
 programmers. 
Hah, I think the same thing every time I'm forced to try to use a boost library. :-) Like just today when I had to go look at Boost::MPL to see what it was all about.
That is a little unfair as you are comparing documentation about a computer language library to documentation about a computer language itself. While I think library documentation can often be better, I am sure that computer language documentation shouold always be very good just to attract people to that language. When one is going head-to-head against the other good and popular which have many detailed books written just on the language itself, one needs to have very good documentation which enables an intelligent programmer to pick up the language easily. After 9 years of D the documentation about the language remains extremely sparse.
 
 In other words it seems as if D should be able to do some of the Boost 
 libraries, which makes C++ so pleasurable to use in general despite 
 the difficulty of dealing with C++ templates, fairly easily. At the 
 same time most of the Boost libraries are tremendously useful. I will 
 look in the Phobos library for their equivalents to see if D has some 
 of the same abilities in its library.
The book with the misleading title is about Tango, actually.
OK. Hopefully it will about D enough for me to pick up the particulars better than I have been able to do from the specification.
 
 Maybe you could tackle porting whatever you find useful about Boost::MPL 
 to D as a first project?  :-)
MPL is a template metaprogramming library which is beyond me in many ways. I wouldn't try to port it to D unless it could be used to create other libraries in D. But trying to port boost::function/boost::bind might be an interesting project. I have already made the point to Walter that since D has delegates and function pointers that they should be merged into a single callable type, which is what boost::function is. Boost::bind is simply a way of creating that callable type while possibly binding arguments to values. Boost::lambda is very similar to boost::bind with a lambda-like syntax.
 
 I'm sure many here would be happy to help.
 (And would also be interested to find out what people find useful about 
 Boost::MPL -- my one experience trying to use Boost::lambda sent me 
 screaming back to good old for loops.)
Really ? I always though using boost::lambda was pretty clear for the main part, while some of its esoteric usages might be a bit strange. The only problem with boost::lambda is that it takes a very conformant C++ compiler. Unfortunately Digital Mars C++ is really not quite good enough to handle many Boost libraries. I think Walter got a little tired of trying to make Digital Mars C++ follow all of the C++ standard, especially as regards templates and/or overloading, where the rules get very arcane, so that may have been another impetus toward creating D where the rules are simpler but perhaps just as effective. In a way I can see why he created D, since C++ is so slow to move forward to fix difficulties and inconsistencies in its syntax, and I am very sympathetic to not having to argue tirelessly with some of the C++ standard committee members who are so locked into the past. Even Stroustrup disappoints me with his argument about having to maintain compatibility with C seemingly forever. C++ should have dropped that necessity a long time ago and moved off on its own in order to make a language that was just as rich but easier to use. Thus D is very interesting to me because it has followed that path. I just need to learn it much better and perhaps appreciate what it can do much better before I take on any serious programming project with it.
Apr 14 2008
prev sibling parent Lars Ivar Igesund <larsivar igesund.net> writes:
Bill Baxter wrote:

 Edward Diener wrote:
 
 D has some really nice features but it really needs much better language
 documentation to attract programmers, especially C++ programmers.
Hah, I think the same thing every time I'm forced to try to use a boost library. :-) Like just today when I had to go look at Boost::MPL to see what it was all about.
 In other words it seems as if D should be able to do some of the Boost
 libraries, which makes C++ so pleasurable to use in general despite the
 difficulty of dealing with C++ templates, fairly easily. At the same
 time most of the Boost libraries are tremendously useful. I will look in
 the Phobos library for their equivalents to see if D has some of the
 same abilities in its library.
The book with the misleading title is about Tango, actually.
"Learn to Tango with D" is definately more about D than about Tango. -- Lars Ivar Igesund blog at http://larsivi.net DSource, #d.tango & #D: larsivi Dancing the Tango
Apr 14 2008
prev sibling parent reply Walter Bright <newshound1 digitalmars.com> writes:
Edward Diener wrote:
 Thanks for the examples above. I do realize that D has some built-in 
 features which enable template manipulation which Boost MPL has to 
 emulate through some very clever C++ template metaprogramming. In 
 particular, as you have shown above, D has the tuple concept, the static 
 if...else, and also something I like quite a bit, which is that there is 
 no necessity for a base template upon which specializations are built 
 but that each template can be defined with its own specializations. That 
 last feature makes D templates really much easier to write.
One aspect of C++ templates is rendered completely irrelevant in D is D's ability to do compile time function execution. Any C++ metaprogramming that computes a value can be replaced in D with an ordinary function, that is then executed at compile time. Other things that help are D's ability to pass strings as template arguments, and parse those strings at compile time, and D's ability to access local variables (not just globals) from template expansions.
Apr 15 2008
parent reply Edward Diener <eddielee_no_spam_here tropicsoft.com> writes:
Walter Bright wrote:
 Edward Diener wrote:
 Thanks for the examples above. I do realize that D has some built-in 
 features which enable template manipulation which Boost MPL has to 
 emulate through some very clever C++ template metaprogramming. In 
 particular, as you have shown above, D has the tuple concept, the 
 static if...else, and also something I like quite a bit, which is that 
 there is no necessity for a base template upon which specializations 
 are built but that each template can be defined with its own 
 specializations. That last feature makes D templates really much 
 easier to write.
One aspect of C++ templates is rendered completely irrelevant in D is D's ability to do compile time function execution. Any C++ metaprogramming that computes a value can be replaced in D with an ordinary function, that is then executed at compile time. Other things that help are D's ability to pass strings as template arguments, and parse those strings at compile time, and D's ability to access local variables (not just globals) from template expansions.
I assume the first means function execution which produces a constant expression. I believe C++ has that on the plate for C++0x, but of course you have evidently have it now. I never realized that a string, by which I believe you mean a string literal, could not be passed as a template argument which is a value and not a type. It does seem an arcane area. The last point I do not follow. Surely a template can access its own member variables, but you seem to be saying that it should access local variables also where it is being instantiated. I can't imagine the usage for that since the template creator can not possibly know where his template is being used. Nonetheless, I will look at these features in order to to understand them better. Templates are fun, and I imagine that D templates will be more fun than C++ templates because they are richer and easier to use.
Apr 15 2008
next sibling parent Walter Bright <newshound1 digitalmars.com> writes:
Edward Diener wrote:
 Walter Bright wrote:
 One aspect of C++ templates is rendered completely irrelevant in D is 
 D's ability to do compile time function execution. Any C++ 
 metaprogramming that computes a value can be replaced in D with an 
 ordinary function, that is then executed at compile time.

 Other things that help are D's ability to pass strings as template 
 arguments, and parse those strings at compile time, and D's ability to 
 access local variables (not just globals) from template expansions.
I assume the first means function execution which produces a constant expression. I believe C++ has that on the plate for C++0x, but of course you have evidently have it now.
C++0x has a "constexpr" proposal, which is a small subset of D's compile time function execution capability. For example, constexpr cannot do recursive functions, loops, if statements, etc.
 I never realized that a string, by which I believe you mean a string 
 literal, could not be passed as a template argument which is a value and 
 not a type. It does seem an arcane area.
It's used in std.algorithms for fun things like specifying the shape of the ordering function used in a sort.
 The last point I do not follow. Surely a template can access its own 
 member variables, but you seem to be saying that it should access local 
 variables also where it is being instantiated. I can't imagine the usage 
 for that since the template creator can not possibly know where his 
 template is being used.
Yes, it can access the local variables from where it is instantiated. (What it does is expand the template into a nested function.) The template designer doesn't need to know, it's just another aliased parameter.
 Nonetheless, I will look at these features in order to to understand 
 them better. Templates are fun, and I imagine that D templates will be 
 more fun than C++ templates because they are richer and easier to use.
Apr 15 2008
prev sibling parent Don Clugston <nospam nospam.com> writes:
Edward Diener Wrote:

 Walter Bright wrote:
 Edward Diener wrote:
 Thanks for the examples above. I do realize that D has some built-in 
 features which enable template manipulation which Boost MPL has to 
 emulate through some very clever C++ template metaprogramming. In 
 particular, as you have shown above, D has the tuple concept, the 
 static if...else, and also something I like quite a bit, which is that 
 there is no necessity for a base template upon which specializations 
 are built but that each template can be defined with its own 
 specializations. That last feature makes D templates really much 
 easier to write.
One aspect of C++ templates is rendered completely irrelevant in D is D's ability to do compile time function execution. Any C++ metaprogramming that computes a value can be replaced in D with an ordinary function, that is then executed at compile time. Other things that help are D's ability to pass strings as template arguments, and parse those strings at compile time, and D's ability to access local variables (not just globals) from template expansions.
I assume the first means function execution which produces a constant expression. I believe C++ has that on the plate for C++0x, but of course you have evidently have it now.
Even if C++ gets it, it'll never be as good. The real fun comes when the compile-time function returns or manipulates a string. I don't think it's possible to do that unless the language has built-in strings and string manipulation.
 
 I never realized that a string, by which I believe you mean a string 
 literal, could not be passed as a template argument which is a value and 
 not a type. It does seem an arcane area.
It's fundamental. AFAIK, C++ gains its Turing-completeness purely from the ability to have integral value template parameters. That's horribly clumsy. With a string, you can encode _anything_. Consequently, instead of that horrible mess you get with expression templates, where an expression is encoded as a tree of types, you can simply encode it as a string. (Particularly nice for encoding a regexp!).
 The last point I do not follow. Surely a template can access its own 
 member variables, but you seem to be saying that it should access local 
 variables also where it is being instantiated. I can't imagine the usage 
 for that since the template creator can not possibly know where his 
 template is being used.
The name of the local variable can be passed as a template parameter.
 
 Nonetheless, I will look at these features in order to to understand 
 them better. Templates are fun, and I imagine that D templates will be 
 more fun than C++ templates because they are richer and easier to use.
Indeed they are. Extremely addictive.
Apr 15 2008
prev sibling parent reply Walter Bright <newshound1 digitalmars.com> writes:
Edward Diener wrote:
 The question is: has anyone tackled in D some of the template 
 metaprogramming tasks which various Boost programmers have accomplished 
 with C++ ?
Yes. See std.algorithms, for one. It is written by Andrei Alexandrescu, the guy who revolutionized template programming in C++ with his book "Modern C++ Design."
 I am trying to get a feel for how different, or how much easier ( or 
 perhaps harder ) it would be to do Boost things like Spirit ( 
 lex/yacc-like DSEL ),
I wrote a toy Spirit clone a while back, just as a proof of concept. It is very doable.
 function ( universal callable ), bind and/or 
 lambda ( function object creation ),
I believe that closures and delegates make those irrelevant.
 shared_ptr ( sharable smart 
 pointer, obviously for RAII in D because of GC ),
Coming with RAII for structs.
 signals ( generalized 
 multicast events ), multi_index ( multiple index containers ),
I'm not sure what those require of templates.
 regex and/or xpressive ( regular expressions ),
Don Clugston showed how you can to regex in D.
 tokenizer ( generalized 
 tokening of strings ), date_time ( date/time and time intervals ) and 
 many others ( the above are just my favorites but I have hardly 
 explored/used all of them ) which C++ programmers find very useful. All 
 of these libraries depend on template metaprogramming in C++. Can their 
 equivalents just as easily be implemented and have any of them been done 
 already ?
Since I've implemented both C++ and D templates, I know what capabilities they have. D's exceeds C++'s.
 I have not looked at the D libraries, phobos and tango I believe they 
 are called, so maybe I am way off base comparing the Boost libraries to 
 what may already be in D. But I am trying to get an idea if D is capable 
 of doing these Boost things just as easily or easier.
For one example, I reduced a whole chapter of Andrei's "Modern C++ Design" to one page of D, see std.typetuple.
Apr 15 2008
next sibling parent reply Jason House <jason.james.house gmail.com> writes:
Walter Bright Wrote:

 Edward Diener wrote:
 The question is: has anyone tackled in D some of the template 
 metaprogramming tasks which various Boost programmers have accomplished 
 with C++ ?
Yes. See std.algorithms, for one. It is written by Andrei Alexandrescu, the guy who revolutionized template programming in C++ with his book "Modern C++ Design." [...] For one example, I reduced a whole chapter of Andrei's "Modern C++ Design" to one page of D, see std.typetuple.
I'd love to see some kind of page comparing D with the contents of Modern C++ Design. It'd be a good selling point for D when the hoards of disgruntled C++ programmers start looking at D. I wonder what could be done within copy right restrictions...
 I am trying to get a feel for how different, or how much easier ( or 
 perhaps harder ) it would be to do Boost things like Spirit ( 
 lex/yacc-like DSEL ),
I wrote a toy Spirit clone a while back, just as a proof of concept. It is very doable.
Would you be willing to add it on dsource, scrapple, etc...? I think the doost project has been inactive for a while...
 function ( universal callable ), bind and/or 
 lambda ( function object creation ),
I believe that closures and delegates make those irrelevant.
Unfortunately not. Function collapses *all* the various function types into one easy to use form. D has both function and delegate, so some 3rd party utility is still needed. Closures capture variables by reference. This means that creating delegates inside a foreach loop (with deferred evaluation) could fail to have the expected behavior. Bind stores stuff by value, so I still find myself using bind libraries.
Apr 15 2008
parent reply Walter Bright <newshound1 digitalmars.com> writes:
Jason House wrote:
 Walter Bright Wrote:
 
 Edward Diener wrote:
 The question is: has anyone tackled in D some of the template 
 metaprogramming tasks which various Boost programmers have
 accomplished with C++ ?
Yes. See std.algorithms, for one. It is written by Andrei Alexandrescu, the guy who revolutionized template programming in C++ with his book "Modern C++ Design." [...] For one example, I reduced a whole chapter of Andrei's "Modern C++ Design" to one page of D, see std.typetuple.
I'd love to see some kind of page comparing D with the contents of Modern C++ Design. It'd be a good selling point for D when the hoards of disgruntled C++ programmers start looking at D. I wonder what could be done within copy right restrictions...
If you want to write such a page, I'm sure Andrei would be willing to discuss it with you.
 I am trying to get a feel for how different, or how much easier (
 or perhaps harder ) it would be to do Boost things like Spirit (
  lex/yacc-like DSEL ),
I wrote a toy Spirit clone a while back, just as a proof of concept. It is very doable.
Would you be willing to add it on dsource, scrapple, etc...? I think the doost project has been inactive for a while...
I don't remember what I did with it <g>.
 function ( universal callable ), bind and/or lambda ( function
 object creation ),
I believe that closures and delegates make those irrelevant.
Unfortunately not. Function collapses *all* the various function types into one easy to use form. D has both function and delegate, so some 3rd party utility is still needed.
I'm not sure that's such a big deal.
 Closures capture variables by reference.  This means that creating
 delegates inside a foreach loop (with deferred evaluation) could fail
 to have the expected behavior.  Bind stores stuff by value, so I
 still find myself using bind libraries.
If you expect captured variables to be by value, sure. But I always expected them to be by reference!
Apr 15 2008
next sibling parent reply Jason House <jason.james.house gmail.com> writes:
Walter Bright wrote:

 Jason House wrote:
 Walter Bright Wrote:
 
 Edward Diener wrote:
 The question is: has anyone tackled in D some of the template
 metaprogramming tasks which various Boost programmers have
 accomplished with C++ ?
Yes. See std.algorithms, for one. It is written by Andrei Alexandrescu, the guy who revolutionized template programming in C++ with his book "Modern C++ Design." [...] For one example, I reduced a whole chapter of Andrei's "Modern C++ Design" to one page of D, see std.typetuple.
I'd love to see some kind of page comparing D with the contents of Modern C++ Design. It'd be a good selling point for D when the hoards of disgruntled C++ programmers start looking at D. I wonder what could be done within copy right restrictions...
If you want to write such a page, I'm sure Andrei would be willing to discuss it with you.
That'd be a nice exercise in learning to stress D :) I'm assuming Andrei won't read and reply to this post, so what would be the next step forward?
 function ( universal callable ), bind and/or lambda ( function
 object creation ),
I believe that closures and delegates make those irrelevant.
Unfortunately not. Function collapses *all* the various function types into one easy to use form. D has both function and delegate, so some 3rd party utility is still needed.
I'm not sure that's such a big deal.
It's a corner case. Corner case elimination is a bigger deal to me than keyword elimination.
 Closures capture variables by reference.  This means that creating
 delegates inside a foreach loop (with deferred evaluation) could fail
 to have the expected behavior.  Bind stores stuff by value, so I
 still find myself using bind libraries.
If you expect captured variables to be by value, sure. But I always expected them to be by reference!
By reference is nice in many cases, but in others it's frustrating. How do you implement the following? foreach(job; queue) runthread(void delegate(){job.execute;}); (Somehow I expect someone to pick apart the example, but I hope the point is clear)
Apr 15 2008
next sibling parent reply Walter Bright <newshound1 digitalmars.com> writes:
Jason House wrote:
 Walter Bright wrote:
 
 Jason House wrote:
 I'd love to see some kind of page comparing D with the contents of
 Modern C++ Design.  It'd be a good selling point for D when the
 hoards of disgruntled C++ programmers start looking at D.  I wonder
 what could be done within copy right restrictions...
If you want to write such a page, I'm sure Andrei would be willing to discuss it with you.
That'd be a nice exercise in learning to stress D :) I'm assuming Andrei won't read and reply to this post, so what would be the next step forward?
You can contact Andrei via his web site http://erdani.org/
 Closures capture variables by reference.  This means that creating
 delegates inside a foreach loop (with deferred evaluation) could fail
 to have the expected behavior.  Bind stores stuff by value, so I
 still find myself using bind libraries.
If you expect captured variables to be by value, sure. But I always expected them to be by reference!
By reference is nice in many cases, but in others it's frustrating. How do you implement the following? foreach(job; queue) runthread(void delegate(){job.execute;}); (Somehow I expect someone to pick apart the example, but I hope the point is clear)
No, the point isn't clear. Closures can handle multiple threads accessing it.
Apr 15 2008
parent reply Jason House <jason.james.house gmail.com> writes:
Walter Bright wrote: 
 Closures capture variables by reference.  This means that creating
 delegates inside a foreach loop (with deferred evaluation) could fail
 to have the expected behavior.  Bind stores stuff by value, so I
 still find myself using bind libraries.
If you expect captured variables to be by value, sure. But I always expected them to be by reference!
By reference is nice in many cases, but in others it's frustrating. How do you implement the following? foreach(job; queue) runthread(void delegate(){job.execute;}); (Somehow I expect someone to pick apart the example, but I hope the point is clear)
No, the point isn't clear. Closures can handle multiple threads accessing it.
I probably should not have rushed to make an example before running out the door. But I'll still run with the example... For each delegate, the job variable gets captured. Each delegate will have access to the job variable. In cases of defered delegate execution, changes to the job variable will affect what the delegate does. In my example, what happens if runthread is really access to a non-blocking thread pool that queues excess commands. When the thread pool gets around to running the delegate passed in, what will be in "job"? If this is done after the loop finishes, the value inside job will be the final value from opApply (or worse, corrupt). The net effect is that a queue of 50 jobs may have the final job executed 50 times, and the first 49 jobs are never run. This does not seem like correct behavior to me.
Apr 15 2008
parent reply Walter Bright <newshound1 digitalmars.com> writes:
Jason House wrote:
 For each delegate, the job variable gets captured.  Each delegate will have
 access to the job variable.  In cases of defered delegate execution,
 changes to the job variable will affect what the delegate does.
 
 In my example, what happens if runthread is really access to a non-blocking
 thread pool that queues excess commands.  When the thread pool gets around
 to running the delegate passed in, what will be in "job"?  If this is done
 after the loop finishes, the value inside job will be the final value from
 opApply (or worse, corrupt).
 
 The net effect is that a queue of 50 jobs may have the final job executed 50
 times, and the first 49 jobs are never run.  This does not seem like
 correct behavior to me.
This is just the usual distinction between value and reference semantics. D does closures by reference. If you want a value, it's simple enough to make a copy. I think D's method is more powerful, because it's a lot harder to make by-value closures into by-reference than the other way around. I also believe D's method is inherently faster, because it isn't necessary to copy the values around (and there can be an arbitrary number of them, and can be arbitrarily large structs).
Apr 15 2008
parent reply Jason House <jason.james.house gmail.com> writes:
Walter Bright Wrote:

 Jason House wrote:
 For each delegate, the job variable gets captured.  Each delegate will have
 access to the job variable.  In cases of defered delegate execution,
 changes to the job variable will affect what the delegate does.
 
 In my example, what happens if runthread is really access to a non-blocking
 thread pool that queues excess commands.  When the thread pool gets around
 to running the delegate passed in, what will be in "job"?  If this is done
 after the loop finishes, the value inside job will be the final value from
 opApply (or worse, corrupt).
 
 The net effect is that a queue of 50 jobs may have the final job executed 50
 times, and the first 49 jobs are never run.  This does not seem like
 correct behavior to me.
This is just the usual distinction between value and reference semantics. D does closures by reference. If you want a value, it's simple enough to make a copy. I think D's method is more powerful, because it's a lot harder to make by-value closures into by-reference than the other way around. I also believe D's method is inherently faster, because it isn't necessary to copy the values around (and there can be an arbitrary number of them, and can be arbitrarily large structs).
The only thing I'm contesting is your statement that closures eliminate the need for a bind library. While it's true they reduce the need for a bind library, they don't eliminate it.
Apr 16 2008
parent reply MatBec <bekkah web.de> writes:
Jason House Wrote:

 The only thing I'm contesting is your statement that closures eliminate the
need for a bind library.  While it's true they reduce the need for a bind
library, they don't eliminate it.
Instead of call some strange bind function just create a closure taking the still unbound arguments that calles the function. I'm not a d-Programmer, but in other languages this is very easy. e.g. Haskell foo x y z = x + y + z bar f = f 9 -- Pass bar a version of foo wich has two arguments bound bar \y -> foo 1 y 7 Or Ruby: def foo (x, y, z) return x + y + z end def bar (f) return f(9) end bar |y| { foo(1, y, 7) } int foo(int x, int y, int z) { return x + y + z; } int bar (Func<int, int> f) { return f(9); } bar(y => foo(1, y, 7)); Is C++'s bind realy any simpler? int foo(int x, int y, int z) { return x + y + z; } int bar (boost:function<int(int)> const & f) { return f(9); } bar(boost::bind(foo, 1, _1, 7));
Apr 16 2008
next sibling parent Bill Baxter <dnewsgroup billbaxter.com> writes:
MatBec wrote:
 Jason House Wrote:
 
 The only thing I'm contesting is your statement that closures eliminate the
need for a bind library.  While it's true they reduce the need for a bind
library, they don't eliminate it.
Instead of call some strange bind function just create a closure taking the still unbound arguments that calles the function. I'm not a d-Programmer, but in other languages this is very easy. e.g. Haskell foo x y z = x + y + z bar f = f 9 -- Pass bar a version of foo wich has two arguments bound bar \y -> foo 1 y 7 Or Ruby: def foo (x, y, z) return x + y + z end def bar (f) return f(9) end bar |y| { foo(1, y, 7) } int foo(int x, int y, int z) { return x + y + z; } int bar (Func<int, int> f) { return f(9); } bar(y => foo(1, y, 7)); Is C++'s bind realy any simpler? int foo(int x, int y, int z) { return x + y + z; } int bar (boost:function<int(int)> const & f) { return f(9); } bar(boost::bind(foo, 1, _1, 7));
Here's the D version for comparison: int foo(int x, int y, int z) { return x + y + z; } int bar (int delegate(int) f) { return f(9); } bar( delegate int(int y){ return foo(1, y, 7); }); // or with inferred return type bar( (int y){ return foo(1, y, 7); }); But that won't work if you pass it a function pointer: int int_to_int(int x) { return x+5; } bar( &int_to_int ); prog.d(39): function bar (int delegate(int)) does not match parameter types (int function(int x)) prog.d(39): Error: cannot implicitly convert expression (& int_to_int) of type int function(int x) to int delegate(int) That's the main thing I'm saying. That conversion should happen implicitly. However, even then it would not be fully general bind replacement. It still would not take a class/struct with opCall or static opCall. struct Callme { int opCall(int x) { return x - 5; } } Callme c; bar( c ); //.. error bar( &c.opCall ); // this is ok, though... Maybe the 'c' in bar(c) above should also be implicitly convertable to int delegate(int)? If so then D's delegates really could eliminate the need for a bind template I think. And thereby make life easier for everyone. --bb
Apr 16 2008
prev sibling next sibling parent Jason House <jason.james.house gmail.com> writes:
MatBec wrote:

 Jason House Wrote:
 
 The only thing I'm contesting is your statement that closures eliminate
 the need for a bind library.  While it's true they reduce the need for a
 bind library, they don't eliminate it.
Instead of call some strange bind function just create a closure taking the still unbound arguments that calles the function. I'm not a d-Programmer, but in other languages this is very easy.
All your examples as written are problem free in D as well. Your examples don't even bind local variables from the caller...
Apr 16 2008
prev sibling parent Leandro Lucarella <llucax gmail.com> writes:
MatBec, el 16 de abril a las 15:40 me escribiste:
 Jason House Wrote:
 
 The only thing I'm contesting is your statement that closures eliminate the
need for a bind library.  While it's true they reduce the need for a bind
library, they don't eliminate it.
Instead of call some strange bind function just create a closure taking the still unbound arguments that calles the function. I'm not a d-Programmer, but in other languages this is very easy. e.g. Haskell foo x y z = x + y + z bar f = f 9 -- Pass bar a version of foo wich has two arguments bound bar \y -> foo 1 y 7
This is called partial function application[1] in Python, which includes a module to do so[2] too. In Haskell is very natural because of the lambda calculus[3]. C++0x will have something similar[4] for templates (which I'm not sure if D support via alias). [1] http://www.python.org/dev/peps/pep-0309/ [2] http://docs.python.org/lib/module-functools.html http://www.python.org/doc/2.5/whatsnew/pep-309.html [3] http://en.wikipedia.org/wiki/Lambda_calculus [4] http://en.wikipedia.org/wiki/C%2B%2B0x#Template_typedefs -- Leandro Lucarella (luca) | Blog colectivo: http://www.mazziblog.com.ar/blog/ ---------------------------------------------------------------------------- GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145 104C 949E BFB6 5F5A 8D05) ---------------------------------------------------------------------------- De tan fina la condesa, por no cagarse, reza. -- Ricardo Vaporeso
Apr 21 2008
prev sibling parent Bruno Medeiros <brunodomedeiros+spam com.gmail> writes:
Jason House wrote:
 
 
 Closures capture variables by reference.  This means that creating
 delegates inside a foreach loop (with deferred evaluation) could fail
 to have the expected behavior.  Bind stores stuff by value, so I
 still find myself using bind libraries.
If you expect captured variables to be by value, sure. But I always expected them to be by reference!
By reference is nice in many cases, but in others it's frustrating. How do you implement the following? foreach(job; queue) runthread(void delegate(){job.execute;}); (Somehow I expect someone to pick apart the example, but I hope the point is clear)
This way: foreach(job; queue) { ({ auto myjob = job; runthread(void delegate(){myjob.execute;}); })(); } And I'm pretty sure that it is only due to a bug that this doesn't work: foreach(job; queue) { auto myjob = job; runthread(void delegate(){myjob.execute;}); } (I'll file a report) Like Walter said, it's a lot harder to make by-value closures into by-reference than the other way around. You may bask in the glory of D now. :) -- Bruno Medeiros - Software Developer, MSc. in CS/E graduate http://www.prowiki.org/wiki4d/wiki.cgi?BrunoMedeiros#D
Apr 25 2008
prev sibling parent reply Edward Diener <eddielee_no_spam_here tropicsoft.com> writes:
Walter Bright wrote:
 Jason House wrote:
 Walter Bright Wrote:

 Edward Diener wrote:
 The question is: has anyone tackled in D some of the template 
 metaprogramming tasks which various Boost programmers have
 accomplished with C++ ?
Yes. See std.algorithms, for one. It is written by Andrei Alexandrescu, the guy who revolutionized template programming in C++ with his book "Modern C++ Design." [...] For one example, I reduced a whole chapter of Andrei's "Modern C++ Design" to one page of D, see std.typetuple.
I'd love to see some kind of page comparing D with the contents of Modern C++ Design. It'd be a good selling point for D when the hoards of disgruntled C++ programmers start looking at D. I wonder what could be done within copy right restrictions...
If you want to write such a page, I'm sure Andrei would be willing to discuss it with you.
 I am trying to get a feel for how different, or how much easier (
 or perhaps harder ) it would be to do Boost things like Spirit (
  lex/yacc-like DSEL ),
I wrote a toy Spirit clone a while back, just as a proof of concept. It is very doable.
Would you be willing to add it on dsource, scrapple, etc...? I think the doost project has been inactive for a while...
I don't remember what I did with it <g>.
 function ( universal callable ), bind and/or lambda ( function
 object creation ),
I believe that closures and delegates make those irrelevant.
Unfortunately not. Function collapses *all* the various function types into one easy to use form. D has both function and delegate, so some 3rd party utility is still needed.
I'm not sure that's such a big deal.
It is only a big deal in the sense that proving a single callback signature or a single event signature, rather than two of each because of the presumed need to support both delegates and function pointers, is a big deal. In other words it is much cleaner to present a single callable interface in a language, ala boost::function, Python callables, callable is a delegate or function pointer as long as the signature matches, so it is a PITA if a language can not fold both into a single callable concept. That is the issue and I think if you think about it you will realize why it is better from both a clarity and ease of use perspective to have a single callable representing both. There is no sense in a language as rich as D to have to move backward from what other other good languages are able to represent.
Apr 15 2008
next sibling parent reply Bill Baxter <dnewsgroup billbaxter.com> writes:
Edward Diener wrote:

 Function collapses *all* the various function types into one easy to
 use form.  D has both function and delegate, so some 3rd party
 utility is still needed.
I'm not sure that's such a big deal.
It is only a big deal in the sense that proving a single callback signature or a single event signature, rather than two of each because of the presumed need to support both delegates and function pointers, is a big deal. In other words it is much cleaner to present a single callable interface in a language, ala boost::function, Python callables, callable is a delegate or function pointer as long as the signature matches, so it is a PITA if a language can not fold both into a single callable concept. That is the issue and I think if you think about it you will realize why it is better from both a clarity and ease of use perspective to have a single callable representing both. There is no sense in a language as rich as D to have to move backward from what other other good languages are able to represent.
I think all that's needed is a way to automatically promote a function to a delegate, right? Then D's delegates basically are the universal callable you're asking for. D needs the function type to be able to interop with C, but there's no reason as far as I know to make it illegal to assign a function to a delegate. It's just that the language doesn't currently allow it. The context pointer inside the delegate would just become null, because the function doesn't need it. --bb
Apr 15 2008
parent Edward Diener <eddielee_no_spam_here tropicsoft.com> writes:
Bill Baxter wrote:
 Edward Diener wrote:
 
 Function collapses *all* the various function types into one easy to
 use form.  D has both function and delegate, so some 3rd party
 utility is still needed.
I'm not sure that's such a big deal.
It is only a big deal in the sense that proving a single callback signature or a single event signature, rather than two of each because of the presumed need to support both delegates and function pointers, is a big deal. In other words it is much cleaner to present a single callable interface in a language, ala boost::function, Python if the callable is a delegate or function pointer as long as the signature matches, so it is a PITA if a language can not fold both into a single callable concept. That is the issue and I think if you think about it you will realize why it is better from both a clarity and ease of use perspective to have a single callable representing both. There is no sense in a language as rich as D to have to move backward from what other other good languages are able to represent.
I think all that's needed is a way to automatically promote a function to a delegate, right? Then D's delegates basically are the universal callable you're asking for. D needs the function type to be able to interop with C, but there's no reason as far as I know to make it illegal to assign a function to a delegate. It's just that the language doesn't currently allow it. The context pointer inside the delegate would just become null, because the function doesn't need it.
I totally agree with what you say here. When a D non-member function can be assigned to a delegate, we have delegate as our D equivalent of delegate.
Apr 16 2008
prev sibling parent reply Walter Bright <newshound1 digitalmars.com> writes:
Edward Diener wrote:
 It is only a big deal in the sense that proving a single callback 
 signature or a single event signature, rather than two of each because 
 of the presumed need to support both delegates and function pointers, is 
 a big deal. In other words it is much cleaner to present a single 
 callable interface in a language, ala boost::function, Python callables, 

 callable is a delegate or function pointer as long as the signature 
 matches, so it is a PITA if a language can not fold both into a single 
 callable concept. That is the issue and I think if you think about it 
 you will realize why it is better from both a clarity and ease of use 
 perspective to have a single callable representing both. There is no 
 sense in a language as rich as D to have to move backward from what 
 other other good languages are able to represent.
There's no reason you cannot write a template in D to do it - Andrei has done so in his std.algorithms code.
Apr 15 2008
parent reply Sean Kelly <sean invisibleduck.org> writes:
== Quote from Walter Bright (newshound1 digitalmars.com)'s article
 Edward Diener wrote:
 It is only a big deal in the sense that proving a single callback
 signature or a single event signature, rather than two of each because
 of the presumed need to support both delegates and function pointers, is
 a big deal. In other words it is much cleaner to present a single
 callable interface in a language, ala boost::function, Python callables,

 callable is a delegate or function pointer as long as the signature
 matches, so it is a PITA if a language can not fold both into a single
 callable concept. That is the issue and I think if you think about it
 you will realize why it is better from both a clarity and ease of use
 perspective to have a single callable representing both. There is no
 sense in a language as rich as D to have to move backward from what
 other other good languages are able to represent.
There's no reason you cannot write a template in D to do it - Andrei has done so in his std.algorithms code.
Sure, but templates don't suit every situation. It's not uncommon for APIs to have to overload on accepting a function and a delegate for flexibility. Sean
Apr 15 2008
parent reply Walter Bright <newshound1 digitalmars.com> writes:
Sean Kelly wrote:
 Sure, but templates don't suit every situation.  It's not uncommon for
 APIs to have to overload on accepting a function and a delegate for
 flexibility.
The only way to merge function pointers with delegates is to have the compiler generate trampolines. This isn't very runtime efficient - the template approach will be faster.
Apr 16 2008
next sibling parent reply "Janice Caron" <caron800 googlemail.com> writes:
On 16/04/2008, Walter Bright <newshound1 digitalmars.com> wrote:
  The only way to merge function pointers with delegates is to have the
 compiler generate trampolines. This isn't very runtime efficient - the
 template approach will be faster.
I think that all that is being suggested is that function (that which you get when you take the address of a static or global function) should implicitly cast to delegate (that which you get when you take the address of a local or member function). I suspect that could be done without too much runtime overhead.
Apr 16 2008
parent reply Sean Kelly <sean invisibleduck.org> writes:
== Quote from Janice Caron (caron800 googlemail.com)'s article
 On 16/04/2008, Walter Bright <newshound1 digitalmars.com> wrote:
  The only way to merge function pointers with delegates is to have the
 compiler generate trampolines. This isn't very runtime efficient - the
 template approach will be faster.
I think that all that is being suggested is that function (that which you get when you take the address of a static or global function) should implicitly cast to delegate (that which you get when you take the address of a local or member function).
I think the problem is that functions and delegates are called differently. That is, the context pointer is passed as an invisible first parameter to a delegate, while functions have no such invisible argument. Interestingly, because the first parameter of a D function is supposed to be passed in a register (EAX) on x86, I think you're right that it should be possible to allow such efficient conversion so long as the D calling convention accounts for it properly (and the platform supports such things). Sean
Apr 16 2008
parent reply Sean Kelly <sean invisibleduck.org> writes:
== Quote from Sean Kelly (sean invisibleduck.org)'s article
 == Quote from Janice Caron (caron800 googlemail.com)'s article
 On 16/04/2008, Walter Bright <newshound1 digitalmars.com> wrote:
  The only way to merge function pointers with delegates is to have the
 compiler generate trampolines. This isn't very runtime efficient - the
 template approach will be faster.
I think that all that is being suggested is that function (that which you get when you take the address of a static or global function) should implicitly cast to delegate (that which you get when you take the address of a local or member function).
I think the problem is that functions and delegates are called differently. That is, the context pointer is passed as an invisible first parameter to a delegate, while functions have no such invisible argument. Interestingly, because the first parameter of a D function is supposed to be passed in a register (EAX) on x86, I think you're right that it should be possible to allow such efficient conversion so long as the D calling convention accounts for it properly (and the platform supports such things).
Er... forget that. A D function would obviously expect its first argument to be in EAX regardless of whether it's a delegate. Some conversion would be necessary unless I'm missing something. Sean
Apr 16 2008
next sibling parent Bill Baxter <dnewsgroup billbaxter.com> writes:
Sean Kelly wrote:
 == Quote from Sean Kelly (sean invisibleduck.org)'s article
 == Quote from Janice Caron (caron800 googlemail.com)'s article
 On 16/04/2008, Walter Bright <newshound1 digitalmars.com> wrote:
  The only way to merge function pointers with delegates is to have the
 compiler generate trampolines. This isn't very runtime efficient - the
 template approach will be faster.
I think that all that is being suggested is that function (that which you get when you take the address of a static or global function) should implicitly cast to delegate (that which you get when you take the address of a local or member function).
I think the problem is that functions and delegates are called differently. That is, the context pointer is passed as an invisible first parameter to a delegate, while functions have no such invisible argument. Interestingly, because the first parameter of a D function is supposed to be passed in a register (EAX) on x86, I think you're right that it should be possible to allow such efficient conversion so long as the D calling convention accounts for it properly (and the platform supports such things).
Er... forget that. A D function would obviously expect its first argument to be in EAX regardless of whether it's a delegate. Some conversion would be necessary unless I'm missing something.
Hmm. Someone wrote a long post about this long ago and claimed to have figured out how to handle it. --bb
Apr 16 2008
prev sibling next sibling parent Kevin Bealer <kevinbealer gmail.com> writes:
Sean Kelly Wrote:

 == Quote from Sean Kelly (sean invisibleduck.org)'s article
 == Quote from Janice Caron (caron800 googlemail.com)'s article
 On 16/04/2008, Walter Bright <newshound1 digitalmars.com> wrote:
  The only way to merge function pointers with delegates is to have the
 compiler generate trampolines. This isn't very runtime efficient - the
 template approach will be faster.
I think that all that is being suggested is that function (that which you get when you take the address of a static or global function) should implicitly cast to delegate (that which you get when you take the address of a local or member function).
I think the problem is that functions and delegates are called differently. That is, the context pointer is passed as an invisible first parameter to a delegate, while functions have no such invisible argument. Interestingly, because the first parameter of a D function is supposed to be passed in a register (EAX) on x86, I think you're right that it should be possible to allow such efficient conversion so long as the D calling convention accounts for it properly (and the platform supports such things).
Er... forget that. A D function would obviously expect its first argument to be in EAX regardless of whether it's a delegate. Some conversion would be necessary unless I'm missing something. Sean
I'm not much of an ASM guru, but I would think that this could be done by "multiple entry point" functions, i.e. prefixes that move registers around. Non-delegate users would not pay for this code, but register-to-register "MOV" should be cheap anyway, since this part of the code only touches fields that must be touched soon anyway, and no branching, jumping, or register saving/unsaving cycles is needed, so it should be pipelinable. Pseudo ASM code: method_start: debug { assert(! this); } mov arg1, arg2 mov arg2, arg3 mov arg3, [non-register argument] (adjust stack fields to indicate 1 fewer arguments?) function_start: (code expecting a1, a2, a3) return ...; I guess this could only apply to "D linkage" functions, since we probably don't know the parentage of C linkage functions, and some won't have the special code. Kevin
Apr 16 2008
prev sibling parent reply Bruno Medeiros <brunodomedeiros+spam com.gmail> writes:
Sean Kelly wrote:
 == Quote from Sean Kelly (sean invisibleduck.org)'s article
 == Quote from Janice Caron (caron800 googlemail.com)'s article
 I think the problem is that functions and delegates are called differently.
 That is, the context pointer is passed as an invisible first parameter to
 a delegate, while functions have no such invisible argument.  Interestingly,
 because the first parameter of a D function is supposed to be passed in a
 register (EAX) on x86, I think you're right that it should be possible to
 allow such efficient conversion so long as the D calling convention
 accounts for it properly (and the platform supports such things).
Er... forget that. A D function would obviously expect its first argument to be in EAX regardless of whether it's a delegate. Some conversion would be necessary unless I'm missing something. Sean
Well, if that doesn't work, there is nothing preventing the *changing* the D function calling ABI, right? Or are there some performance, or other issues? -- Bruno Medeiros - Software Developer, MSc. in CS/E graduate http://www.prowiki.org/wiki4d/wiki.cgi?BrunoMedeiros#D
Apr 27 2008
next sibling parent "Janice Caron" <caron800 googlemail.com> writes:
 == Quote from Janice Caron (caron800 googlemail.com)'s article
 I think the problem is that functions and delegates are called
 differently... <snip> ... (and the platform supports such things)
This is /not/ a quote from me. This is a quote from Sean Kelly.
Apr 27 2008
prev sibling parent Sean Kelly <sean invisibleduck.org> writes:
Bruno Medeiros wrote:
 Sean Kelly wrote:
 == Quote from Sean Kelly (sean invisibleduck.org)'s article
 == Quote from Janice Caron (caron800 googlemail.com)'s article
 I think the problem is that functions and delegates are called 
 differently.
 That is, the context pointer is passed as an invisible first 
 parameter to
 a delegate, while functions have no such invisible argument.  
 Interestingly,
 because the first parameter of a D function is supposed to be passed 
 in a
 register (EAX) on x86, I think you're right that it should be 
 possible to
 allow such efficient conversion so long as the D calling convention
 accounts for it properly (and the platform supports such things).
Er... forget that. A D function would obviously expect its first argument to be in EAX regardless of whether it's a delegate. Some conversion would be necessary unless I'm missing something.
Well, if that doesn't work, there is nothing preventing the *changing* the D function calling ABI, right? Or are there some performance, or other issues?
Well... I suppose the D ABI could state that if a function has a context pointer then this value is passed in a specific register (EAX), and that the register may not be used for parameter passing otherwise. Then I think it should be possible to call any D function as if it were a delegate. Sean
Apr 27 2008
prev sibling next sibling parent reply Sean Kelly <sean invisibleduck.org> writes:
== Quote from Walter Bright (newshound1 digitalmars.com)'s article
 Sean Kelly wrote:
 Sure, but templates don't suit every situation.  It's not uncommon for
 APIs to have to overload on accepting a function and a delegate for
 flexibility.
The only way to merge function pointers with delegates is to have the compiler generate trampolines. This isn't very runtime efficient - the template approach will be faster.
Certainly. Templates are always faster. But they don't always suit. To choose the simplest example, let's say that I want to ship a library with no source code exposed. Templates are obviously out. Now, to support callable parameters I must either overload routines for both function and delegate simply to account for pointers to global vs. non-global callable routines, or I need to use a wrapper object to pass instead. Either way, the same efficiency is lost, and I'm stuck doing a bunch of wrapping or conversion in library code as well. Now perhaps the library is indeed the best place for this, but either way I disagree that "just use templates because they're faster" is an acceptable solution for every situation. The 80-20 rule dictates that generalized arguments about performance are baseless anyway because 80% of the time the performance difference isn't even noticeable. Rather, I would argue that in such instances elegance is of utmost importance because of its effect on code maintainability. The great thing about D is that it often manages to achieve top-tier performance in an eminently elegant manner. Sean
Apr 16 2008
parent Bill Baxter <dnewsgroup billbaxter.com> writes:
Sean Kelly wrote:
 == Quote from Walter Bright (newshound1 digitalmars.com)'s article
 Sean Kelly wrote:
 Sure, but templates don't suit every situation.  It's not uncommon for
 APIs to have to overload on accepting a function and a delegate for
 flexibility.
The only way to merge function pointers with delegates is to have the compiler generate trampolines. This isn't very runtime efficient - the template approach will be faster.
Certainly. Templates are always faster. But they don't always suit. To choose the simplest example, let's say that I want to ship a library with no source code exposed. Templates are obviously out. Now, to support callable parameters I must either overload routines for both function and delegate simply to account for pointers to global vs. non-global callable routines, or I need to use a wrapper object to pass instead. Either way, the same efficiency is lost, and I'm stuck doing a bunch of wrapping or conversion in library code as well. Now perhaps the library is indeed the best place for this, but either way I disagree that "just use templates because they're faster" is an acceptable solution for every situation. The 80-20 rule dictates that generalized arguments about performance are baseless anyway because 80% of the time the performance difference isn't even noticeable. Rather, I would argue that in such instances elegance is of utmost importance because of its effect on code maintainability. The great thing about D is that it often manages to achieve top-tier performance in an eminently elegant manner.
callable. Something like setCallback(&fn). --bb
Apr 16 2008
prev sibling next sibling parent Edward Diener <eddielee_no_spam_here tropicsoft.com> writes:
Walter Bright wrote:
 Sean Kelly wrote:
 Sure, but templates don't suit every situation.  It's not uncommon for
 APIs to have to overload on accepting a function and a delegate for
 flexibility.
The only way to merge function pointers with delegates is to have the compiler generate trampolines. This isn't very runtime efficient - the template approach will be faster.
The template approach means that one has to write a template for each function signature, uniting D function pointers and D delegates, which one wants to use as a callback or event in one's own code, unless of course one does the equivalent of boost::function in D for nn parameters as a generalized template solution. Finally if a delegate in D is the equivalent of an object pointer and a member function pointer, why would allowing a null pointer for the object pointer part not allow a delegate to encompass both a non-member function pointer and an object's member function pointer ? If it would, then is it really that much slower checking if the object pointer is null to decide internally in code how the delegate is called ?
Apr 16 2008
prev sibling parent reply Tomas Lindquist Olsen <tomas famolsen.dk> writes:
Walter Bright wrote:
 Sean Kelly wrote:
 Sure, but templates don't suit every situation.  It's not uncommon for
 APIs to have to overload on accepting a function and a delegate for
 flexibility.
The only way to merge function pointers with delegates is to have the compiler generate trampolines. This isn't very runtime efficient - the template approach will be faster.
I was reading about these a few days ago, as LLVM has support for these. Basically it's also how GCC implements its nested function extension. I figured someone else might find this link interesting! There's a link to a paper on trampolines in the article linked as well: http://gcc.gnu.org/onlinedocs/gcc/Nested-Functions.html
Apr 18 2008
parent Bill Baxter <dnewsgroup billbaxter.com> writes:
Tomas Lindquist Olsen wrote:
 Walter Bright wrote:
 Sean Kelly wrote:
 Sure, but templates don't suit every situation.  It's not uncommon for
 APIs to have to overload on accepting a function and a delegate for
 flexibility.
The only way to merge function pointers with delegates is to have the compiler generate trampolines. This isn't very runtime efficient - the template approach will be faster.
I was reading about these a few days ago, as LLVM has support for these. Basically it's also how GCC implements its nested function extension. I figured someone else might find this link interesting! There's a link to a paper on trampolines in the article linked as well: http://gcc.gnu.org/onlinedocs/gcc/Nested-Functions.html
So you mean if one uses GDC, then all calls to nested functions are handled using trampolines? Or only if you take the address of a nested function and try to call that? Anyway I totally don't see any problem with generating a trampoline in order to let a user assign a function pointer to a delegate pointer variable. The people who are obsessed with the performance difference can make special cases for function pointers vs delegate pointers, but the rest of just go about our merry business. --bb
Apr 18 2008
prev sibling parent reply Edward Diener <eddielee_no_spam_here tropicsoft.com> writes:
Walter Bright wrote:
 Edward Diener wrote:
 The question is: has anyone tackled in D some of the template 
 metaprogramming tasks which various Boost programmers have 
 accomplished with C++ ?
Yes. See std.algorithms, for one. It is written by Andrei Alexandrescu, the guy who revolutionized template programming in C++ with his book "Modern C++ Design."
I know of Andrei and his book. The Boost MPL superceded what he had done, but that does not take away from the value of his original work.
 
 I am trying to get a feel for how different, or how much easier ( or 
 perhaps harder ) it would be to do Boost things like Spirit ( 
 lex/yacc-like DSEL ),
I wrote a toy Spirit clone a while back, just as a proof of concept. It is very doable.
Good to hear. Then maybe someone will write a real parser in D as rich as Spirit, or mayber someone already has. Despite C++ template's intricacy, Spirit is a monstrously wonderful piece of software. My hat is off to Joel Guzman and Hartmut Kaiser for it.
 
 function ( universal callable ), bind and/or lambda ( function object 
 creation ),
I believe that closures and delegates make those irrelevant.
I believe you are wrong unless you have managed to combine all callables into a single syntax, and have a flexible binding mechanism built into the callable concept. But we had this discussion before where I pointed out that having both delegates and function pointers in D was bifurcating a common concept ( callable ), and that you should serious think about combining them, either through the languiage or perhaps a library, into one. In C++, boost::function is that library and bind/lambda essentially creates callables with various very flexible argument binding mechanisms. Perhaps D 2.0 can do all that but my reading of D 1.0 says no.
 
 shared_ptr ( sharable smart pointer, obviously for RAII in D because 
 of GC ),
Coming with RAII for structs.
I hope it will eventually be coming some day with RAII via scope, per our long thread/discussion.
 
 signals ( generalized multicast events ), multi_index ( multiple index 
 containers ),
I'm not sure what those require of templates.
Signals are built on top of boost::function, and is essentially a multi-cast closure for any type of callable. Other than that it is probably no more template based than boost::function. But since Boost::function has to deal in types for all possibilities of function objects up to nn ( defaulted to 10 I believe ) parameters and a return type, boost::signals has to also.
 
 regex and/or xpressive ( regular expressions ),
Don Clugston showed how you can to regex in D.
Yes, I realized that D has regular expressions in one of it libraries, which is great. Congratulations !
 
 tokenizer ( generalized tokening of strings ), date_time ( date/time 
 and time intervals ) and many others ( the above are just my favorites 
 but I have hardly explored/used all of them ) which C++ programmers 
 find very useful. All of these libraries depend on template 
 metaprogramming in C++. Can their equivalents just as easily be 
 implemented and have any of them been done already ?
Since I've implemented both C++ and D templates, I know what capabilities they have. D's exceeds C++'s.
Good to hear. Now that I understand D templates better I can play with them a little more. I still have a gut feeling that D may need an equivalent template library like the Boost MPL for compile time type manipulation in order to achive the sort of complicated template metaprogramming usage that so many Boost libraries have in order to accomplish their ends, but I can not prove it and could be entirely wrong about it. Perhaps the Boost MPL is a way to do things with C++ templates which D already natively provides with D templates.
 
 I have not looked at the D libraries, phobos and tango I believe they 
 are called, so maybe I am way off base comparing the Boost libraries 
 to what may already be in D. But I am trying to get an idea if D is 
 capable of doing these Boost things just as easily or easier.
For one example, I reduced a whole chapter of Andrei's "Modern C++ Design" to one page of D, see std.typetuple.
Is that why Andrei became interested in D <g> ?
Apr 15 2008
parent reply Walter Bright <newshound1 digitalmars.com> writes:
Edward Diener wrote:
 Is that why Andrei became interested in D <g> ?
I don't wish to put words in Andrei's mouth, except to say that we are really, really fortunate to have Andrei helping us out with D.
Apr 15 2008
parent Edward Diener <eddielee_no_spam_here tropicsoft.com> writes:
Walter Bright wrote:
 Edward Diener wrote:
 Is that why Andrei became interested in D <g> ?
I don't wish to put words in Andrei's mouth, except to say that we are really, really fortunate to have Andrei helping us out with D.
I was largely joking, via the <g>. I am aware of Andrei butting heads with others on comp.std.c++ and comp.lang.c++ ( I have occasionally done the same myself ).
Apr 15 2008
prev sibling parent Georg Wrede <georg nospam.org> writes:
Walter Bright wrote:
 Edward Diener wrote:
 Walter Bright wrote:
 Kevin Bealer wrote:

 I was amazed that Boost could do things like the Lambda support with 
 _1 _2, etc. Those Boost guys are geniuses.
I agree, they are geniuses. But that's really what is wrong with C++, you shouldn't have to be a genius to get advanced things done.
Are D's templates a complete replacement in functionality for Boost's MPL ? If so could you write an article on your web site about the how's and why's of that ? I am still trying to understand D's templates based on the sparse documentation of them.
I don't really understand Boost MPL, but D's template system is considerably more powerful than C++'s. I agree that more documentation is needed, *but one can easily write a book about it*.
[my bold above] ROTFLMHO! :-) :-) :-) :-) :-) :-) :-) Marketing talk aside, I doubt if anyone thinks even D's templates are /that/ easy. (Sorry, couldn't resist. I assume you actually meant the issue is broad enough. But I /did/ lough out aloud.)
 Remember that part of the difficult for the Boost developer is also 
 supporting many non-conforming C++ compilers, so part of the genius of 
 what they are doing is manipulating around compilers that do not deal 
 with C++ templates correctly ( perhaps because the details of the C++ 
 template system are so abstruse and difficult to understand and 
 implement).
It's amazing even not considering compiler bug workarounds. And yes, a large reason for the compiler bugs is because it is so hard to understand how it is supposed to work.
(OT:) I think we're missing the point here. Suppose someone finds archives about C++, compiler development, C++ Standards Committee's memoranda, drafts and decrees, after /a hundred/ years have passed. Then one sees *in hindsight* how persistently and altruistically folks tackle the "hard" parts of computing, irrespectively of if they represent /actually/ Hard problems, or just something that's hard because other people did a sloppy job! I mean, today we just "live with" the C++ spec. With any distance (be it geographical (as in on the Moon) or temporal (as in looking at our times as they were some Western movies), it *immediately* becomes painfully obvious that nobody should accept such a situation without rebellion. And all the more because "C++ is The Programming Language" of our time.
Apr 13 2008
prev sibling next sibling parent reply Bill Baxter <dnewsgroup billbaxter.com> writes:
Georg Wrede wrote:
 I read
 
 http://www.nwcpp.org/Downloads/2007/redcode_-_updated.pdf
 
 and upon reading it I got thinking of something else. Those familiar 
 with C++ (aren't we all?) probably sometimes come across things that 
 somebody has done in C++ that are simply stunning. Things that one would 
 have thought would need a new language, or maybe just be impossible to 
 implement at all. I know I have. (A lot of Boost stuff is like that, 
 originally the STL got me breathless, but there's a lot that's not 
 template related, too.)
 
 Is it just paranoia, or is C++ still more flexible and expressive than D?
 
 Are there still things you can do in C++ that are impossible or too 
 awkward to do in D?
 
 Of course, I don't mean Obfuscated C(++). While that definitely 
 demonstrates the unfathomable agility of the language, I'm only talking 
 about serious, non-juvenile stuff.
Structs would be my vote for the area where C++ is more flexible and expressive than D. But Walter realizes this and it's on the plate. Some sort of destructor support was added in the last update, and inheritance was promised in the slides at last year's D conference. So D will catch up in that arena. Metaprogramming is definitely the area where D is light years ahead of C++. --bb
Apr 10 2008
parent "Craig Black" <cblack ara.com> writes:
 Structs would be my vote for the area where C++ is more flexible and 
 expressive than D.  But Walter realizes this and it's on the plate. Some 
 sort of destructor support was added in the last update, and inheritance 
 was promised in the slides at last year's D conference.  So D will catch 
 up in that arena.

 Metaprogramming is definitely the area where D is light years ahead of 
 C++.

 --bb
Agree on all points. Overall, D is much more elegant and expressive than C++, especially with templates. With better support for structs, D will allow more flexibility for high-performance data structures. IMO, the next steps for closing the performance gap with C++ would be to optimize the GC and the compiler back-end. Once these optimizations are in place, D should be on par with C++ performance-wise. What's more, if the right features are implemented, D performance could potentially surpass C++ in the next five years or so. -Craig
Apr 11 2008
prev sibling next sibling parent reply Kevin Bealer <kevinbealer gmail.com> writes:
Sean Kelly Wrote:

 == Quote from Kevin Bealer (kevinbealer gmail.com)'s article
 Out of curiosity, what motivates your desire for placement new?
Constructing D objects in shared memory. That's also an underlying reason why I added a way to override object monitors in Tango. Sean
I wondered about this myself -- at one point I sat down and designed a bunch of code in C++ that used relative pointers and memory mapped areas. The idea was to have a complete set of tools for created "tied" containers and so on in memory mapped files, so that you could create documents and random data structures without considering the data format itself. The relative pointer idea is that a smart pointer could be defined that actually stored the pointed to value minus the pointer's address. This allows you to point to other objects in the same memory mapped arena regardless of where it gets mapped to. It's also nearly free to use these because the address of the pointer being dereferenced is always itself in a register, so the cost of dereferencing is exactly one subtraction with no IO overhead. You can also use 32 bit pointers regardless of platform as long as your arena is <= 2GB, but you need to worry about endianness. Alternately, you could use 64 bit pointers with multi-document systems but takes more computation. Of course you need to redefine every type you use with this system -- even C++ classes that use allocator template parameters rarely come in a form that is templatized on smart-pointer type. (And if you use virtual pointers, you need to do something about that -- I had some ideas but I never finished that part of it.) Kevin
Apr 11 2008
parent Sean Kelly <sean invisibleduck.org> writes:
== Quote from Kevin Bealer (kevinbealer gmail.com)'s article
 Sean Kelly Wrote:
 == Quote from Kevin Bealer (kevinbealer gmail.com)'s article
 Out of curiosity, what motivates your desire for placement new?
Constructing D objects in shared memory. That's also an underlying reason why I added a way to override object monitors in Tango.
I wondered about this myself -- at one point I sat down and designed a bunch of code in C++ that used relative pointers and memory mapped areas. The idea was to have a complete set of tools for created "tied" containers and so on in memory mapped files, so that you could create documents and random data structures without considering the data format itself. The relative pointer idea is that a smart pointer could be defined that actually stored the pointed to value
minus the pointer's address. This allows you to point to other objects in
 the same memory mapped arena regardless of where it gets mapped to.
It's a bit tricky, but so long as you map the file at the same address in every app using it then you can actually use absolute addressing and have it work. The tricky bit ends up being making sure that the vtbl pointers are valid, etc. I actually worked on a (patented) object database type system that stores all of its data as memory-mapped C++ objects which are used directly from their mapped location using such tricks. It's unbelievably fast and does all the mapping and unmapping automatically as the applications run. I'd do something comparable for D but for my exposure to the project--it's just too much of an IP risk, even not considering the patent.
 Of course you need to redefine every type you use with this system -- even C++
classes that use allocator
template parameters rarely come in a form that is templatized on smart-pointer type. (And if you use virtual pointers, you need to do something about that -- I had some ideas but I never finished that part of it.) In C++ you can supply a custom allocator that typedefs those smart pointers as the pointer type. As much as those allocators complicate container design in C++, they offer an incredibly flexible design. If you wanted to, I suspect you could even make an STL allocator that used a SQL database for storage. Sean
Apr 11 2008
prev sibling next sibling parent reply bearophile <bearophileHUGS lycos.com> writes:
I can't follow the newsgroup now, but I'd really like to know if you can use D
to implement the tricks used by the Blitz++ C++ lib
(http://www.oonumerics.org/blitz/ ).

bearophile
Apr 15 2008
parent reply "Janice Caron" <caron800 googlemail.com> writes:
On 15/04/2008, bearophile <bearophileHUGS lycos.com> wrote:
 I can't follow the newsgroup now, but I'd really like to know if you can use D
to implement the tricks used by the Blitz++ C++ lib
(http://www.oonumerics.org/blitz/ ).
Given that D templates are way, way, /way/ more powerful than C++ templates, what's to stop you?
Apr 15 2008
parent Bill Baxter <dnewsgroup billbaxter.com> writes:
Janice Caron wrote:
 On 15/04/2008, bearophile <bearophileHUGS lycos.com> wrote:
 I can't follow the newsgroup now, but I'd really like to know if you can use D
to implement the tricks used by the Blitz++ C++ lib
(http://www.oonumerics.org/blitz/ ).
Given that D templates are way, way, /way/ more powerful than C++ templates, what's to stop you?
The fact that D structs are way way /way/ more wimpy than C++ structs. :-) But that's changing. Also that argument deduction in D templates isn't very complete. Nested types mess it up, like Mike Parker found just recently in another thread. Lack of template overloading and of overloading across modules can cause headaches too. requires that you use various shades of "unnatural" syntax like expr.AssignTo(r) instead of r = expr: http://www.codeproject.com/KB/recipes/dynmatrixmath.aspx D could at least do better than that, I'm sure. --bb
Apr 15 2008
prev sibling parent reply Don Clugston <nospam nospam.com> writes:
Edward Diener Wrote:

 Bill Baxter wrote:
 Edward Diener wrote:
 
 D has some really nice features but it really needs much better 
 language documentation to attract programmers, especially C++ 
 programmers. 
Hah, I think the same thing every time I'm forced to try to use a boost library. :-) Like just today when I had to go look at Boost::MPL to see what it was all about.
That is a little unfair as you are comparing documentation about a computer language library to documentation about a computer language itself.
I think it's reasonable -- boost is increasingly looking like a standard library for C++; it can be compared to D's library docs, at least. Your point about D's docs is valid, though -- they could certainly be better.
 The book with the misleading title is about Tango, actually.
OK. Hopefully it will about D enough for me to pick up the particulars better than I have been able to do from the specification.
My opinion (as the technical reviewer of the book) was that the template section discussed things from a C++ mindset, which is probably helpful for a C++ programmer; yet it gives less detail on the interesting unique-to-D stuff which renders many C++ techniques obsolete. The underlying "problem" is that about a year ago, Walter suddenly stuffed a raft of enormously powerful features into the language in a very short space of time. Suddenly we had tuples, string mixins, and CTFE, and D wasn't playing catch-up with C++ any more. The showcase examples of template metaprogramming became obsolete overnight. We still haven't worked out the idioms for how to use it all; there are some fascinating synergies with existing features. Which makes documentation, especially the most useful "how-to" kind quite difficult to write at this stage. But I reckon a "metaprogramming tips and tricks" Wiki page would be pretty useful. -Don.
Apr 15 2008
parent reply Sean Kelly <sean invisibleduck.org> writes:
== Quote from Don Clugston (nospam nospam.com)'s article
 Edward Diener Wrote:
 OK. Hopefully it will about D enough for me to pick up the particulars
 better than I have been able to do from the specification.
My opinion (as the technical reviewer of the book) was that the template section discussed things from a C++ mindset, which is probably
helpful for a C++ programmer; yet it gives less detail on the interesting unique-to-D stuff which renders many C++ techniques obsolete. Yup. That was a somewhat contentious decision on my part. Since C++ is the only other language with templates I wanted to be sure the reader understood templates in general with the hope that it would provide a good base to build on. As a result, because of the length limitation of the book, the chapter doesn't talk too much about some of the newer or more advanced features that D offers such as tuples. Regarding "Tango with D" in general though... very little of the book is Tango-specific. We made a deliberate effort to make the language our primary focus. Sean
Apr 15 2008
parent Jesse Phillips <jessekphillips gmail.com> writes:
On Tue, 15 Apr 2008 21:37:41 +0000, Sean Kelly wrote:

 == Quote from Don Clugston (nospam nospam.com)'s article
 Edward Diener Wrote:
 OK. Hopefully it will about D enough for me to pick up the
 particulars better than I have been able to do from the
 specification.
My opinion (as the technical reviewer of the book) was that the template section discussed things from a C++ mindset, which is probably
helpful for a C++ programmer; yet it gives less detail on the interesting unique-to-D stuff which renders many C++ techniques obsolete. Yup. That was a somewhat contentious decision on my part. Since C++ is the only other language with templates I wanted to be sure the reader understood templates in general with the hope that it would provide a good base to build on. As a result, because of the length limitation of the book, the chapter doesn't talk too much about some of the newer or more advanced features that D offers such as tuples. Regarding "Tango with D" in general though... very little of the book is Tango-specific. We made a deliberate effort to make the language our primary focus. Sean
I would like to compliment that effort, as it is IMO that the book was very well section in terms of what is D and what is Tango. I also think the book was very well written by all authors. I hope a book that goes into more of the specialties and details of D can be written with this quality.
Apr 15 2008