How does D improve design practices over C++?

Janderson ask at me.com
Wed Nov 5 08:39:42 PST 2008


Tony wrote:
 > "Janderson" <ask at me.com> wrote in message 
news:gepsn2$21jr$1 at digitalmars.com...
 >> Tony wrote:
 >>> Let me be facetious with Janderson's list plz...
 >>>
 >>> "Janderson" <ask at me.com> wrote in message 
news:ge8tpd$1f6b$1 at digitalmars.com...
 >>>> Hi,
 >>>>
 >>>> I was talking with some collages at work and they asked me how D 
enforces good programming practices.   For course I mentioned a couple 
of the ones I knew of hand -
 >>>>
 >>>> - Unit checking
 >>> Not sure what is meant by this, but it sounds minor.
 >> Sure C++ can do unit checking, but its not built in.  You have to 
use macros or templates in something that is not really designed to work 
correctly with the language.  Even if you ignore that there's a barrior 
to entry by not having something like this in the language.  By having 
it in the language good coding practices are encouraged.
 >
 > I write unit tests. I don't know why I'd need or want language 
support for that.


What api do you use?  All the api's I've used are not as nice as the 
built in one for D.


 >
 >>>> - Design by contract
 >>> Overblown concept, but can be done with C++ also to a more than 
adequate degree (heard of assertions?).
 >> Yes this can be done with C++ but D takes it it many steps further.
 >
 > Like I said, I find the techniques more important that some 
implementation of them (mechanism rather than policy?).

D contracts take this one step futher then C++.  They allow one to 
decouple the contracts from the code itself:

long square_root(long x)
     in
     {
     assert(x >= 0);
     }
     out (result)
     {
     assert((result * result) <= x && (result+1) * (result+1) >= x);
     }
     body
     {
     return cast(long)std.math.sqrt(cast(real)x);
     }

D also has better compile time messages.  It also support static asserts.


 >
 >>>> - Invariant checks
 >>> Part of DbC concepts. See Koenig and Moo's array example in 
"Accelerated C++". Which, btw, leads me to believe that there are few 
instances "where the stars line up just right" for invariant checking to 
be useful.
 >> Invariant checks can be done in C++ but its very unweildly.  It is 
very annoying to have to instruct each function with scope guards.  D 
encourages good invariant checking by making it easy.
 >
 > But again, I am thinking that the scenarios where invariants can be 
established is a very small subset of classes.
 >

I think the best programmers use invariant checks a whole lot.

 >>
 >>>> - Stronger const
 >>> Insignificant. I still use many #defines just because I know that 
const vars take space and #defines are a pre-compile-time thing (yes, I 
value the preprocessor for some uses, this being one of them).
 >> Actually any good compiler will inline const variables but I'm not 
talking about those sort of const.  Also you pay 2 costs for using #define:
 >>
 >> 1) its not typesafe
 >> 2) it adds to your compile time because the pre-processor has to do 
more.
 >
 > Coming from the Windows world, one isn't "afraid" of 1 above 
whatsoever. Compile time? CPUs are evolving faster than I'll ever be 
able to outpace them with the complexity or volume of my software.

I guess for u compilation time isn't a problem.  It is for me.  Every 
large project I've worked on gets to a point where compile time is a 
problem.  Partly because of use of code-generation (templates) which yes 
slow things down but is also generating a load of code I don't have to.

Also #defines really arn't a problem for cpu at compile time, your right 
there.  I'm trying to point out that using #defines for const is totally 
rediculus (sorry for being so harsh).  No C++ book or expert would 
recommend it and it doesn't result in any run-time optimisation what so 
ever.

 >
 >> I'm talking about the const you put in function declarations which 
are very important.
 >>
 >>
 >>>> - Modules
 >>> If that means doing away with header files, I don't think I like 
it. I rely on headers as the engineer's blueprint (of course you have to 
write very clean code to have that make sense).
 >> I think this means you simply haven't run up against any of the 
problems with header files.
 >
 > That's probably exactly what it means. But maybe I'm tooling up to 
write utility software rather than large scale software.

That could be so.  D does seem targeted at large scale software.  For me 
that's great.  That's the thing with C verse C++.  I think C is great 
until you have to write something large that is maintainable.  C++/D has 
a lot of scaffolding and that only starts to pay dividends when the code 
gets larger.  At some point a C++ program will be smaller then a C program.

 >
 >>>> - Garbage collection
 >>> That's a major deal breaker for me.
 >> Garbage collection can be turned off in D if you don't need it.
 >
 > So I've been told. But I think the default should be to include it 
when you like rather than the other way around. Obviously, I can use a 
GC library in C++ if I was so inclined.

This is a good debatable point.  I don't agree but that's just because 
of all the headakes I've had to track down with manual management.


 >
 >> However for me (even when performance is very important and a game 
programmer) I can deal with it.
 >>
 >>>> - No automatic copy constructor
 >>> Can't comment.
 >> I'd encourage you to read "See C++ Coding Standards: 101 Rules, 
Guidelines, and Best Practices (C++ In-Depth Series)" by Herb Sutter, 
Andrei Alexandrescu
 >> 
http://www.amazon.com/Coding-Standards-Guidelines-Practices-Depth/dp/0321113586
 >> one of the only books that has Bjarne Stroustrups seal of approval.
 >
 >> Effective C++ is another good read.
 >
 > Been there a number of times. Automatic copy constructor issue didn't 
catch my eye though obviously.

In C++ its standard practice by most programmers to disable the copy 
constructor for many of the classes they create.  Some companies it 
mandatory to either disable it or implement one.

 >
 >>
 >>>> - More restrictive operators
 >>> I'm not really concerned about that. I'd avoid them unless doing 
numerical programming.
 >> The point here is that in C++ operators where used for all sorts of 
things that they where not designed for.  This makes code hard to follow.
 >
 > I whole heartedly agree!
 >
 >> D restricts operators making them more difficult to use for 
something they are not really designed for, ie encouraging better design.
 >
 > Minor. I know when not to use operators (read: hardly ever!).

For you this might not be a useful feature however for many others it 
is, and that is who I was address when I wrote this document.  With 
small apps with short development cycles you have intimate knowledge 
about everything that makes it tick.  With large apps you have to 
communicate though code.  A language that enforces some sort of 
standards and documentation (ie even key words as simple as interface) 
will ultimately help others with that communication.  Also when I go 
back to the code in 6months I will have a better understanding of it 
because the compiler prevented me from writting something that was 
nonsensical.

 >>>> - Specific constructs such as Interfaces
 >>> C++ has interfaces. Should it be a keyword? Maybe. How are D's 
interfaces different from C++'s?
 >> C++ has interfaces which can easily become abstractions.  This is 
not good.  By saying something is an interface, your documenting -> this 
is an interface don't change me.  Its much better when the code can 
enforce rules rather then by just comments.  You look at an interface in 
D and you know its an interface, C++ you have to read though the code or 
hope someone has documented it.  I'm not the best explainer in the world 
so maybe someone else can explain this better.
 >
 > I use naming standards for interfaces: iSomeClass, for example. I'm 
not sure what problem D's interfaces solve. I find no problem with C++'s 
interface techniques.
 >

Compiler checked documentation.  This is an interface and that's what it 
is.  Don't make it abstract.  It a built in naming and enforced 
convention.  Also I know there's lots of heat around styles however 
having things like "i" in front of classes means that you can't change 
what that thing is (well you can in you have access to the user-code and 
what to do a find-replace).

 >>>> - More restrictive casting
 >>> Ouch!! I prefer to slice bread with a knife rather than having a 
machine do it. (Bad analogy, but y'all get the point).
 >> I'd rather the machine catch something at compile time rather then 
runtime.
 >
 > As long as I'm not prevented from doing casting I know is safe, it's 
fine.

That's the point of casts right :)   You can always cast to what you 
want in D however the more dangerous ones can be slightly harder to do.

 >
 >>>> - No C style Macros
 >>> Implementing a template or template system with a good preprocessor 
is something completely different than macros. I value the preprocessor 
for such uses (I wish it was more powerful than in C++ though).
 >> Macros in C++, powerful yes but I think they are over used.
 >
 > Macros and using the preprocessor as a template machine are apples 
and oranges. Every use of the the C++ preprocessor does not fit the 
definition of "macro", thought everyone pounces on the obvious as you do 
below:
 >
 >> D has a replacement for the macro system which is more powerful. 
Most of which is not done in the preprocess.  I've seen more horrible 
C++ macros then I can count.  They are definably not a good practice. 
Any good C++ books will talk about "Macro side effects".  They arn't 
typesafe, there's a possibility of having an operation performed in a 
place you don't expect.  They don't work will on multilines (i hate \ 
because its not maintainable and error prone).  Doing things like string 
operations are just non-intuitive.
 >>
 >> The other bad thing about macros is they are extremely difficult to 
debug.
 >>
 >> D provides many of the functionalities of macros in a nicer form:
 >> - Better Templates
 >> - Mixins
 >> - Version
 >>
 >> Site note: About ~80% of macros I've seen in C++ could have been 
done with templates in C++ and they would have been much better in so 
many ways.
 >
 > Tony



More information about the Digitalmars-d mailing list