How does D improve design practices over C++?
Tony
tonytech08 at gmail.com
Thu Nov 6 13:57:33 PST 2008
"Janderson" <ask at me.com> wrote in message
news:gesi8g$4ii$3 at digitalmars.com...
> 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.
In-house/proprietary, but it's hardly anything automated such as I'm sure
there are commercial offerings for. I'm not close enough to deployment to
worry about detailed testing: there are still some architectural issues to
solve for higher level framework components.
>
>
> >
> >>>> - 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);
> }
Or if one wanted something like that in C++:
class MyInvariant
{
MyInvariant(long& x)
{
// do a check on entry
}
~MyInvariant()
{
// do a check on exit
}
};
>
> 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.
If one has a lot of opportunity to use invariants, I'll bet it has to do
with the domain. Such as numerical programming: that would seem to have a
lot of those opportunities for use of invariant checking. In other domains
(mainstream GUI dev?), much less so or even rarely so.
>
> >>
> >>>> - 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.
I'll bet it's a design problem rather than a template machinery problem.
Templates are way overused IMO, and few people know how to or just don't
bother architecting nice generic classes and functions.
>
> 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.
Obviously I take language feature "recommendation" with a grain of salt. I
do #define because I've never had any problem with it (and look at the
Windows header files sometime!) and #defines don't create a data object in
memory. It's simply never been a problem. Now if one is "hell bent/anal"
about "doing away with the preprocessor, power to them, "it ain't me"
though. I don't want the template machinery taking over the capability of
the preprocessor: I use it to mutate the language and experiment. I will
probably implement a preprocessor to replace or add to what I have with C++
before I jump into compiler development for my language that is evolving.
>
> >
> >> 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.
I do that too: I "disable" (declare private and don't supply an
implementation") the compiler-called class functions by default when
designing a class and putting them back if they are needed.
>
> >
> >>
> >>>> - 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 guess for D it is a bigger issue because header files are frowned upon?
The header file in C++ is the first level of documentation, and if you code
cleanly, maybe all that is required. Combine that with some
design/architecture description and most of the documentation chore is done.
> >
> > 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.
Again though, "macros" and "preprocessor-implemented templates" are not the
same thing, but I'd rather not go round and round on this.
Tony
More information about the Digitalmars-d
mailing list