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