February 05, 2005
"Matthew" <admin@stlsoft.dot.dot.dot.dot.org> wrote in message news:cu1q0r$1609$1@digitaldaemon.com...
>
> "Vathix" <vathix@dprogramming.com> wrote in message news:opslo861ihkcck4r@esi...
>>>> Guys, if we persist with the mechanism of no compile-time detection of return paths
>>>
>>> "and switch cases"
>>>
>>>> , and rely on the runtime exceptions, do we really think NASA would use D? Come on!
>>>
>>
>> Would you fly to mars in debug mode?
>
> Well, to seriously answer your question: I think production code, at least for 'important commercial', should be shipped with contract programming enforcement on.
>

How about some middle ground?

class Foo
{
    ...
    invariant(X) // runs with debug=X
    {
        ...
    }
    int foo(int i)
    in(Y) {}    // runs with debug=Y
    out(Y) {}
    body(Z) {} // "error: missing body { ... } after in or out" if debug=Y
but not debug=Z
}

Then you could do this:

dmd -O -inline -release -debug=X -debug=Y foo.d  (-release and -debug are mutually exclusive, but not -release and -debug=ident)

And the contract code could be turned on/off via already built-in command line functionality and keywords.

Would it create a mess for compiler implementors to do something like this (Walter)?

Would it make sense in the commercial world where PwC is used (like your last project, Matthew)?

IMO, this could give the best of both worlds. Keep the contracts where they are really needed but let the optimizer do it's thing everywhere else like remove asserts and array bounds checking.

- Dave


February 05, 2005
> IMO, this could give the best of both worlds.

I would even settle for less , like a -release-with-cp flag.

Charlie


"Dave" <Dave_member@pathlink.com> wrote in message news:cu2uq3$288a$1@digitaldaemon.com...
>
> "Matthew" <admin@stlsoft.dot.dot.dot.dot.org> wrote in message news:cu1q0r$1609$1@digitaldaemon.com...
> >
> > "Vathix" <vathix@dprogramming.com> wrote in message news:opslo861ihkcck4r@esi...
> >>>> Guys, if we persist with the mechanism of no compile-time detection
of
> >>>> return paths
> >>>
> >>> "and switch cases"
> >>>
> >>>> , and rely on the runtime exceptions, do we really think NASA would
use
> >>>> D? Come on!
> >>>
> >>
> >> Would you fly to mars in debug mode?
> >
> > Well, to seriously answer your question: I think production code, at
least
> > for 'important commercial', should be shipped with contract programming enforcement on.
> >
>
> How about some middle ground?
>
> class Foo
> {
>     ...
>     invariant(X) // runs with debug=X
>     {
>         ...
>     }
>     int foo(int i)
>     in(Y) {}    // runs with debug=Y
>     out(Y) {}
>     body(Z) {} // "error: missing body { ... } after in or out" if debug=Y
> but not debug=Z
> }
>
> Then you could do this:
>
> dmd -O -inline -release -debug=X -debug=Y foo.d  (-release and -debug are mutually exclusive, but not -release and -debug=ident)
>
> And the contract code could be turned on/off via already built-in command line functionality and keywords.
>
> Would it create a mess for compiler implementors to do something like this
> (Walter)?
>
> Would it make sense in the commercial world where PwC is used (like your
> last project, Matthew)?
>
> IMO, this could give the best of both worlds. Keep the contracts where
they
> are really needed but let the optimizer do it's thing everywhere else like remove asserts and array bounds checking.
>
> - Dave
>
>




February 05, 2005
I can see both your points.  And I do not want to gang up on Walter but

> Q: Do you think driving on the left-hand side of the road is more or
> less sensible than driving on the right?
> A: When driving on the left-hand side of the road, be careful to monitor
> junctions from the left.

represents allot of responses from Walter when he's dead set on something.

I agree that putting in "shut-up" code can indeed lead to more bugs like Walter was saying , but in this case , I don't think that a 'return' statement is one of them.  Using C/C++ its always been an error on my compilers to not have a return statement, and its _never_ been a problem ( probably saved many bugs because of it ).  Have to agree 100% with Matthew on that one.

Now a switch with no default and no matching 'case' ? I can see the argument for that.  I think that is a good example of 'shut-up code' doing harm, where its better caught at runtime then at compile time.  But its almost GUARANTEED not to run right with a missing return statement , best to catch it at compile time.

Charlie



"Matthew" <admin@stlsoft.dot.dot.dot.dot.org> wrote in message news:cu23g5$1hh3$1@digitaldaemon.com...
> > "Matthew" <admin@stlsoft.dot.dot.dot.dot.org> wrote in message news:cu1pe6$15ks$1@digitaldaemon.com...
> >> > 1) make it impossible to ignore situations the programmer did not think of
> >>
> >> So do I. So does any sane person.
> >>
> >> But it's a question of level, context, time. You're talking about two
> >> measures that are small-scale, whose effects may or may not ever be
> >> seen
> >> in a running system . If they do, they may or may not be in a
> >> context,
> >> and at a time, which renders them useless as an aid to improving the
> >> program.
> >
> > If the error is silently ignored, it will be orders of magnitude
> > harder to
> > find. Throwing in a return 0; to get the compiler to stop squawking is
> > not
> > helping.
>
> I'm not arguing for that!
>
> You have the bad habit of attributing positions to me that are either more extreme, or not representative whatsoever, in order to have something against which to argue more strongly. (You're not unique in that, of course. I'm sure I do it as well sometimes.)
>
> >> > 2) the bias is to force bugs to show themselves in an obvious manner.
> >>
> >> So do I.
> >>
> >> But this statement is too bland to be worth anything. What's is "obvious"?
> >
> > Throwing an uncaught exception is designed to be obvious and is the preferred method of being obvious about a runtime error.
>
> Man oh man! Have you taken up politics?
>
> My problem is that you're forcing issues that can be dealt with at compile time to be runtime. Your response: exceptions are the best way to indicate runtime error.
>
> Come on.
>
> Q: Do you think driving on the left-hand side of the road is more or
> less sensible than driving on the right?
> A: When driving on the left-hand side of the road, be careful to monitor
> junctions from the left.
>
> >> *Who decides* what is obvious? How does/should the bug show itself? When should the showing be done: early, or late?
> >
> > As early as possible. Putting in the return 0; means the showing will
> > be
> > late.
>
> Oh? And that'd be later than the compiler preventing it from even getting to object code in the first place?
>
> >> Frankly, one might argue that the notion that the language and its
> >> premier compiler actively work to _prevent_ the programmer from
> >> detecting bugs at compile-time, forcing a wait of an unknowable
> >> amount
> >> of testing (or, more horribly, deployment time) to find them, is
> >> simply
> >> crazy.
> >
> > I understand your point, but for this case, I do not agree for all the
> > reasons stated here. I.e. there are other factors at work, factors
> > that will
> > make the bugs harder to find, not easier, if your approach is used. It
> > is
> > recognition of how programmers really write code, rather than the way
> > they
> > are exhorted to write code.
>
> Disagree.
>
> >> But you're hamstringing 100% of all developers for the careless/unprofessional/inept of a few.
> >
> > I don't believe it is a few. It is enough that Java was forced to
> > change
> > things, to allow unchecked exceptions. People who look at a lot of
> > Java code
> > and work with a lot of Java programmers tell me it is a commonplace
> > practice, *even* among the experts. When even the experts tend to
> > write code
> > that is wrong even though they know it is wrong and tell others it is
> > wrong,
> > is a very strong signal that the language requirement they are dealing
> > with
> > is broken. I don't want to design a language that the experts will say
> > "do
> > as I say, not as I do."
>
> Yet again, you are broad-brushing your arbitrary (or at least partial) absolute decisions with a complete furphy. This is not an analogy, it's a mirror with some smoke machines behind it.
>
> >> Will those handful % of better-employed-working-in-the-spam-industry
> >> find no other way to screw up their systems? Is this really going to
> >> answer all the issues attendant with a lack of
> >> skill/learning/professionalism/adequate quality mechanisms (incl,
> >> design
> >> reviews, code reviews, documentation, refactoring, unit testing,
> >> system
> >> testing, etc. etc. )?
> >
> > D is based on my experience and that of many others on how programmers
> > actually write code, rather than how we might wish them to.
> > (Supporting a
> > compiler means I see an awful lot of real world code!) D shouldn't
> > force
> > people to insert dead code into their source. It's tedious, it looks
> > wrong,
> > it's misleading, and it entices bad habits even from expert
> > programmers.
>
> Sorry, but wrong again. As I mentioned in the last post, there's a mechanism for addressing both camps, yet you're still banging on with this all-or-nothing position.
>
> >> But I'm not going to argue point by point with your post, since you
> >> lost
> >> me at "Java's exceptions". The analogy is specious, and thus
> >> unconvincing. (Though I absolutely concur that they were a little
> >> tried
> >> 'good idea', like C++'s exception specifications or, in fear of
> >> drawing
> >> unwanted venom from my friends in the C++ firmament, export.)
> >
> > I believe it is an apt analogy as it shows how forcing programmers to
> > do
> > something unnatural leads to worse problems than it tries to solve.
> > The best
> > that can be said for it is "it seemed like a good idea at the time". I
> > was
> > at the last C++ standard committee meeting, and the topic came up on
> > booting
> > exception specifications out of C++ completely. The consensus was that
> > it
> > was now recognized as a worthless feature, but it did no harm (since
> > it was
> > optional), so leave it in for legacy compatibility.
>
> All of this is of virtually no relevance to the topic under discussion
>
> > There's some growing thought that even static type checking is an
> > emperor
> > without clothes, that dynamic type checking (like Python does) is more
> > robust and more productive. I'm not at all convinced of that yet <g>,
> > but
> > it's fun seeing the conventional wisdom being challenged. It's good
> > for all
> > of us.
>
> I'm with you there.
>
> >> My position is simply that compile-time error detection is better
> >> than
> >> runtime error detection.
> >
> > In general, I agree with that statement. I do not agree that it is
> > always
> > true, especially in this case, as it is not necessarilly an error. It
> > is
> > hypothetically an error.
>
> Nothing is *always* true. That's kind of one of the bases of my thesis.
>
> >> Now you're absolutely correct that an invalid state throwing an
> >> exception, leading to application/system reset is a good thing.
> >> Absolutely. But let's be honest. All that achieves is to prevent a
> >> bad
> >> program from continuing to function once it is established to be bad.
> >> It
> >> doesn't make that program less bad, or help it run well again.
> >
> > Oh, yes it does make it less bad! It enables the program to notify the
> > system that it has failed, and the backup needs to be engaged. That
> > can make
> > the difference between an annoyance and a catastrophe. It can help it
> > run
> > well again, as the error is found closer to the the source of it,
> > meaning it
> > will be easier to reproduce, find and correct.
>
> Sorry, but this is totally misleading nonsense. Again, you're arguing against me as if I think runtime checking is invalid or useless. Nothing could be further from the truth.
>
> So, again, my position is: Checking for an invalid state at runtime, and acting on it in a non-ignorable manner, is the absolute best thing one can do. Except when that error can be detected at runtime.
>
> Please stop arguing against your demons on this, and address my point. If an error can be detected at compile time, then it is a mistake to detect it at runtime. Please address this specific point, and stop general carping at the non-CP adherents. I'm not one of 'em.
>
> >> Depending
> >> on the vaguaries of its operating environment, it may well just keep
> >> going bad, in the same (hopefully very short) amount of time, again
> >> and
> >> again and again. The system's not being (further) corrupted, but it's
> >> not getting anything done either.
> >
> > One of the Mars landers went silent for a couple days. Turns out it
> > was a
> > self detected fault, which caused a reset, then the fault, then the
> > reset,
> > etc. This resetting did eventually allow JPL to wrest control of it
> > back. If
> > it had simply locked, oh well.
>
> Abso-bloody-lutely spot on behaviour. What: you think I'm arguing that the lander should have all its checking done at compile time (as if that's even possible) and eschew runtime checking.
>
> At no time have I ever said such a thing.
>
> > On airliners, the self detected faults trigger a dedicated circuit
> > that
> > disables the faulty computer and engages the backup. The last, last,
> > last
> > thing you want the autopilot on an airliner to do is execute a return
> > 0;
> > some programmer threw in to shut the compiler up. An exception thrown,
> > shutting down the autopilot, engaging the backup, and notifying the
> > pilot is
> > what you'd much rather happen.
>
> Same as above. Please address my thesis, not the more conveniently down-shootable one you seem to have addressing.
>
> >> It's clear, or seems to to me, that this issue, at least as far as
> >> the
> >> strictures of D is concerned, is a balance between the likelihoods
> >> of:
> >>     1.    producing a non-violating program, and
> >>     2.    preventing a violating program from continuing its
> >> execution
> >> and, therefore, potentially wreck a system.
> >
> > There's a very, very important additional point - that of not enticing
> > the
> > programmer into inserting "shut up" code to please the compiler that
> > winds
> > up masking a bug.
>
> Absolutely. But that is not, in and of itself, sufficient justification for ditching compile detection in favour of runtime detection. Yet again, we're having to swallow absolutism - dare I say dogma? - instead of coming up with a solution that handles all requirements to a healthy degree.
>
> >> You seem to be of the opinion that the current situation of missing
> >> return/case handling (MRCH) minimises the likelihood of 2. I agree
> >> that
> >> it does so.
> >>
> >> However, contrarily, I assert that D's MRCH minimises the likelihood
> >> of
> >> producing a non-violating program in the first place. The reasons are
> >> obvious, so I'll not go into them. (If anyone's cares to disagree, I
> >> ask
> >> you to write a non-trival C++ program in a hurry, disable *all*
> >> warnings, and go straight to production with it.)
> >>
> >> Walter, I think that you've hung D on the petard of 'absolutism in
> >> the
> >> name of simplicity', on this and other issues. For good reasons, you
> >> won't conscience warnings, or pragmas, or even switch/function
> >> decoarator keywords (e.g. "int allcases func(int i) { if i < 0
> >> return -1'; }"). Indeed, as I think most participants will
> >> acknowledge,
> >> there are good reasons for all the decisions made for D thus far. But
> >> there are also good reasons against most/all of those decisions.
> >> (Except
> >> for slices. Slices are *the best thing* ever, and coupled with
> >> auto+GC,
> >> will eventually stand D out from all other mainstream languages.<G>).
> >
> > Jan Knepper came up with the slicing idea. Sheer genius!
>
> Truly
>
> >> Software engineering hasn't yet found a perfect language. D is not
> >> perfect, and it'd be surprising to hear anyone here say that it is.
> >> That
> >> being the case, how can the policy of absolutism be deemed a sensible
> >> one?
> >
> > Now that you set yourself up, I can't resist knocking you down with
> > "My
> > position is simply that compile-time error detection is better than
> > runtime
> > error detection." :-)
>
> ?
>
> If you're trying to say that I've implied that compile-time detection can handle everything, leaving nothing to be done at runtime, you're either kidding, sly, or mental. I'm assuming kidding, from the smiley, but it's a bit disingenuous at this level of the debate, don't you think?
>
> >> It cannot be sanely argued that throwing on missing returns is a
> >> perfect
> >> solution, any more than it can be argued that compiler errors on
> >> missing
> >> returns is. That being the case, why has D made manifest in its
> >> definition the stance that one of these positions is indeed perfect?
> >
> > I don't believe it is perfect. I believe it is the best balance of
> > competing
> > factors.
>
> I know you do. We all know that you do. It's just that many disagree that it is. That's one of the problems.
>
> >> I know the many dark roads that await once the tight control on the
> >> language is loosened, but the real world's already here, batting on
> >> the
> >> door. I have an open mind, and willing fingers to all kinds of
> >> languages. I like D a lot, and I want it to succeed a *very great
> >> deal*.
> >> But I really cannot imagine recommending use of D to my clients with
> >> these flaws of absolutism. (My hopeful guess for the future is that
> >> other compiler variants will arise that will, at least, allow
> >> warnings
> >> to detect such things at compile time, which may alter the commercial
> >> landscape markedly; D is, after all, full of a great many wonderful
> >> things.)
> >
> > I have no problem at all with somebody making a "lint" for D that will
> > explore other ideas on checking for errors. One of the reasons the
> > front end
> > is open source is so that anyone can easily make such a tool.
>
> I'm not talking about lint. I confidently predict that the least badness that will happen will be the general use of non-standard compilers and the general un-use of DMD. But I realistically think that D'll splinter as a result of making the same kinds of mistakes, albeit for different reasons, as C++. :-(
>
> >> One last word: I recall a suggestion a year or so ago that would
> >> required the programmer to explicitly insert what is currently
> >> inserted
> >> implicitly. This would have the compiler report errors to me if I
> >> missed
> >> a return. It'd have the code throw errors to you if an unexpected
> >> code
> >> path occured. Other than screwing over people who prize typing one
> >> less
> >> line over robustness, what's the flaw? And yet it got no traction
> >> ....
> >
> > Essentially, that means requiring the programmer to insert:
> >    assert(0);
> >    return 0;
>
> That is not the suggested syntax, at least not to the best of my recollection.
>
> > It just seems that requiring some fixed boilerplate to be inserted
> > means
> > that the language should do that for you. After all, that's what
> > computers
> > are good at!
>
> LOL! Well, there's no arguing with you there, eh?
>
> You don't want the compiler to automate the bits I want. I don't want it to automate the bits you want. I suggest a way to resolve this, by requiring more of the programmer - fancy that! - and you discount that because it's something the compiler should do.
>
> Just in case anyone's missed the extreme illogic of that position, I'll reiterate.
>
>     Camp A want behaviour X to be done automatically by the compiler
>     Camp B want behaviour Y to be done automatically by the compiler. X
> and Y are incompatible, when done automatically.
>     By having Z done manually, X and Y are moot, and everything works
> well. (To the degree that D will, then, and only then, achieve resultant
> robustnesses undreamt of.)
>
>     Walter reckons that Z should be done automatically by the compiler.
> Matthew auto-defolicalises and goes to wibble his frimble in the back
> drim-drim with the other nimpins.
>
> Less insanely, I'm keen to hear if there's any on-point response to this?
>
> >> [My goodness! That was way longer than I wanted. I guess we'll still
> >> be
> >> arguing about this when the third edition of DPD's running hot
> >> through
> >> the presses ...]
> >
> > I don't expect we'll agree on this anytime soon.
>
> Agreed
>
>


February 05, 2005
"Derek" <derek@psych.ward> wrote in message news:1uqf5a6fc42ei$.8hb72yklj5d2.dlg@40tude.net...
> You seem to be concerned that a code will always insert 'dead code' just
so
> the compiler will stop nagging them.

Always? No. But it happens much more often than one would think. It usually happens when one is in a hurry, or thinking about something else at the time. One promises oneself that one will go back and fix it later. But that never happens.

> I'm 50 years old and I've been coding for 28 years. You will often find in my code such things as ...
>
>   Abort("Logic Error #nnn. If you see this, a mistake was made by the
> programmer. This should never be seen. Inform your supplier about this
> message.");
>
> You might regard this is superfluous 'dead code',

No, I do not. I think such practice as yours is fine. My concern is with the temptation to just insert a return statement without any abort call. I've seen it happen, a lot, by professional programmers. This is where the good intentions of the compiler error message have gone awry and caused things to be worse.

> however a 'nice' message
> from the coder to the user is better than a compiler generated 'jargon'
> message that the user must decode.

This is good, and is also achievable by putting a catch in at the top level to catch any wayward uncaught exceptions and print out any message desired.

> Thus my switch constructs always have a
> default clause,

That's my normal practice with C/C++ code, years ago I had a paper
advocating such called "Defensive Programming". Many of those ideas have
been automated in D, as D will insert a default clause for you if none is
specified, and that inserted default clause will throw an exception. It
takes the place of all the
    default: assert(0); break;
I write in C/C++. I think we are much more in agreement on these issues than
not.

> and any 'if' statement in which an unhandled false would
> cause problems, I have an 'else' phrase. I always have a return statement
> at the end of my function text, even if its will never be executed (if all
> goes well). Call it overkill if you like, but in the long run, it keeps
the
> users better informed and *more* importantly, keeps future maintainers aware of the previous coder's intentions and reasons for doing things.

No, I don't regard it as overkill. But I would regard an inserted return statement (that is not preceded by one of the abort messages you showed above) that is not intended to ever be executed as masking a potential bug.

I also believe that dead code, unless it is marked with an Abort() like your example, is a problem for future maintainers. He'll see that return, and wonder what it's for and why it doesn't seem to be possible to execute it. (As an aside, it's interesting how much dead code tends to accumulate in an app. You can find such by running a coverage analyzer. Dead code accumulates like all the useless DNA we carry around <g>. I've been thinking of writing such a tool for D, it would be a good complement to the profiler.)

> Currently, D is way too dogmatic and unreasonably unhelpful to the coder.

But I think that a compiler requiring dead code to be inserted is being dogmatic! <g> Guess it's all in one's perspective.

> It is mostly still better than C/C++ though.

I surely hope so!


February 05, 2005
I just think that we should have CP and debug/release somewhat independent.

Ideally, I'd like

    "-debug" to have debugging info _and_ CP
    "-release" to have CP
    "-release -contracts=off" to have neither

and, if anyone's that perverse

    "-debug -contracts=off" to have debugging info only

This all seems eminently straightforward. The only 'twist' is that CP is on by default, unless one explicitly requests it to be off. (I'm sure we can now start a heated battle about that ...)

"Charles" <no@email.com> wrote in message news:cu36bt$2f2h$1@digitaldaemon.com...
>> IMO, this could give the best of both worlds.
>
> I would even settle for less , like a -release-with-cp flag.
>
> Charlie
>
>
> "Dave" <Dave_member@pathlink.com> wrote in message news:cu2uq3$288a$1@digitaldaemon.com...
>>
>> "Matthew" <admin@stlsoft.dot.dot.dot.dot.org> wrote in message news:cu1q0r$1609$1@digitaldaemon.com...
>> >
>> > "Vathix" <vathix@dprogramming.com> wrote in message news:opslo861ihkcck4r@esi...
>> >>>> Guys, if we persist with the mechanism of no compile-time detection
> of
>> >>>> return paths
>> >>>
>> >>> "and switch cases"
>> >>>
>> >>>> , and rely on the runtime exceptions, do we really think NASA would
> use
>> >>>> D? Come on!
>> >>>
>> >>
>> >> Would you fly to mars in debug mode?
>> >
>> > Well, to seriously answer your question: I think production code, at
> least
>> > for 'important commercial', should be shipped with contract
>> > programming
>> > enforcement on.
>> >
>>
>> How about some middle ground?
>>
>> class Foo
>> {
>>     ...
>>     invariant(X) // runs with debug=X
>>     {
>>         ...
>>     }
>>     int foo(int i)
>>     in(Y) {}    // runs with debug=Y
>>     out(Y) {}
>>     body(Z) {} // "error: missing body { ... } after in or out" if
>> debug=Y
>> but not debug=Z
>> }
>>
>> Then you could do this:
>>
>> dmd -O -inline -release -debug=X -debug=Y foo.d  (-release and -debug
>> are
>> mutually exclusive, but not -release and -debug=ident)
>>
>> And the contract code could be turned on/off via already built-in
>> command
>> line functionality and keywords.
>>
>> Would it create a mess for compiler implementors to do something like
>> this
>> (Walter)?
>>
>> Would it make sense in the commercial world where PwC is used (like
>> your
>> last project, Matthew)?
>>
>> IMO, this could give the best of both worlds. Keep the contracts where
> they
>> are really needed but let the optimizer do it's thing everywhere else
>> like
>> remove asserts and array bounds checking.
>>
>> - Dave
>>
>>
>
>
>
> 


February 05, 2005
> I can see both your points.  And I do not want to gang up on Walter but
>
> represents allot of responses from Walter when he's dead set on something.
>

Yes. Kind of like calling upon a disinterested god.

A night's sleep has interveened, and I tire of smashing my head on the same brick wall, so I'll segue on y'all to say:

>> Q: Do you think driving on the left-hand side of the road is more or
>> less sensible than driving on the right?
>> A: When driving on the left-hand side of the road, be careful to
>> monitor
>> junctions from the left.

Given the fact that the majority of people are right-handed, and steering correctly is probably more important than changing gear correctly, driving on the LHS is the better thing. So nya nya from the Australasia/Japan/UK to all the rest of the world.

Of course, an increasing number of people drive automatics, to it's largely moot. And then there's that bizarre steering wheel change business that you NW hemisphere types enjoy, which totally blows my argument.

:-)

"Charles" <no@email.com> wrote in message news:cu3747$2foi$1@digitaldaemon.com...
>
> I can see both your points.  And I do not want to gang up on Walter but
>
>> Q: Do you think driving on the left-hand side of the road is more or
>> less sensible than driving on the right?
>> A: When driving on the left-hand side of the road, be careful to
>> monitor
>> junctions from the left.
>
> represents allot of responses from Walter when he's dead set on something.
>
> I agree that putting in "shut-up" code can indeed lead to more bugs
> like
> Walter was saying , but in this case , I don't think that a 'return'
> statement is one of them.  Using C/C++ its always been an error on my
> compilers to not have a return statement, and its _never_ been a
> problem (
> probably saved many bugs because of it ).  Have to agree 100% with
> Matthew
> on that one.
>
> Now a switch with no default and no matching 'case' ? I can see the
> argument
> for that.  I think that is a good example of 'shut-up code' doing
> harm,
> where its better caught at runtime then at compile time.  But its
> almost
> GUARANTEED not to run right with a missing return statement , best to
> catch
> it at compile time.
>
> Charlie
>
>
>
> "Matthew" <admin@stlsoft.dot.dot.dot.dot.org> wrote in message news:cu23g5$1hh3$1@digitaldaemon.com...
>> > "Matthew" <admin@stlsoft.dot.dot.dot.dot.org> wrote in message news:cu1pe6$15ks$1@digitaldaemon.com...
>> >> > 1) make it impossible to ignore situations the programmer did
>> >> > not
>> >> > think of
>> >>
>> >> So do I. So does any sane person.
>> >>
>> >> But it's a question of level, context, time. You're talking about
>> >> two
>> >> measures that are small-scale, whose effects may or may not ever
>> >> be
>> >> seen
>> >> in a running system . If they do, they may or may not be in a
>> >> context,
>> >> and at a time, which renders them useless as an aid to improving
>> >> the
>> >> program.
>> >
>> > If the error is silently ignored, it will be orders of magnitude
>> > harder to
>> > find. Throwing in a return 0; to get the compiler to stop squawking
>> > is
>> > not
>> > helping.
>>
>> I'm not arguing for that!
>>
>> You have the bad habit of attributing positions to me that are either more extreme, or not representative whatsoever, in order to have something against which to argue more strongly. (You're not unique in that, of course. I'm sure I do it as well sometimes.)
>>
>> >> > 2) the bias is to force bugs to show themselves in an obvious manner.
>> >>
>> >> So do I.
>> >>
>> >> But this statement is too bland to be worth anything. What's is "obvious"?
>> >
>> > Throwing an uncaught exception is designed to be obvious and is the preferred method of being obvious about a runtime error.
>>
>> Man oh man! Have you taken up politics?
>>
>> My problem is that you're forcing issues that can be dealt with at
>> compile time to be runtime. Your response: exceptions are the best
>> way
>> to indicate runtime error.
>>
>> Come on.
>>
>> Q: Do you think driving on the left-hand side of the road is more or
>> less sensible than driving on the right?
>> A: When driving on the left-hand side of the road, be careful to
>> monitor
>> junctions from the left.
>>
>> >> *Who decides* what is obvious? How does/should the bug show itself? When should the showing be done: early, or late?
>> >
>> > As early as possible. Putting in the return 0; means the showing
>> > will
>> > be
>> > late.
>>
>> Oh? And that'd be later than the compiler preventing it from even getting to object code in the first place?
>>
>> >> Frankly, one might argue that the notion that the language and its
>> >> premier compiler actively work to _prevent_ the programmer from
>> >> detecting bugs at compile-time, forcing a wait of an unknowable
>> >> amount
>> >> of testing (or, more horribly, deployment time) to find them, is
>> >> simply
>> >> crazy.
>> >
>> > I understand your point, but for this case, I do not agree for all
>> > the
>> > reasons stated here. I.e. there are other factors at work, factors
>> > that will
>> > make the bugs harder to find, not easier, if your approach is used.
>> > It
>> > is
>> > recognition of how programmers really write code, rather than the
>> > way
>> > they
>> > are exhorted to write code.
>>
>> Disagree.
>>
>> >> But you're hamstringing 100% of all developers for the careless/unprofessional/inept of a few.
>> >
>> > I don't believe it is a few. It is enough that Java was forced to
>> > change
>> > things, to allow unchecked exceptions. People who look at a lot of
>> > Java code
>> > and work with a lot of Java programmers tell me it is a commonplace
>> > practice, *even* among the experts. When even the experts tend to
>> > write code
>> > that is wrong even though they know it is wrong and tell others it
>> > is
>> > wrong,
>> > is a very strong signal that the language requirement they are
>> > dealing
>> > with
>> > is broken. I don't want to design a language that the experts will
>> > say
>> > "do
>> > as I say, not as I do."
>>
>> Yet again, you are broad-brushing your arbitrary (or at least
>> partial)
>> absolute decisions with a complete furphy. This is not an analogy,
>> it's
>> a mirror with some smoke machines behind it.
>>
>> >> Will those handful % of
>> >> better-employed-working-in-the-spam-industry
>> >> find no other way to screw up their systems? Is this really going
>> >> to
>> >> answer all the issues attendant with a lack of
>> >> skill/learning/professionalism/adequate quality mechanisms (incl,
>> >> design
>> >> reviews, code reviews, documentation, refactoring, unit testing,
>> >> system
>> >> testing, etc. etc. )?
>> >
>> > D is based on my experience and that of many others on how
>> > programmers
>> > actually write code, rather than how we might wish them to.
>> > (Supporting a
>> > compiler means I see an awful lot of real world code!) D shouldn't
>> > force
>> > people to insert dead code into their source. It's tedious, it
>> > looks
>> > wrong,
>> > it's misleading, and it entices bad habits even from expert
>> > programmers.
>>
>> Sorry, but wrong again. As I mentioned in the last post, there's a mechanism for addressing both camps, yet you're still banging on with this all-or-nothing position.
>>
>> >> But I'm not going to argue point by point with your post, since
>> >> you
>> >> lost
>> >> me at "Java's exceptions". The analogy is specious, and thus
>> >> unconvincing. (Though I absolutely concur that they were a little
>> >> tried
>> >> 'good idea', like C++'s exception specifications or, in fear of
>> >> drawing
>> >> unwanted venom from my friends in the C++ firmament, export.)
>> >
>> > I believe it is an apt analogy as it shows how forcing programmers
>> > to
>> > do
>> > something unnatural leads to worse problems than it tries to solve.
>> > The best
>> > that can be said for it is "it seemed like a good idea at the
>> > time". I
>> > was
>> > at the last C++ standard committee meeting, and the topic came up
>> > on
>> > booting
>> > exception specifications out of C++ completely. The consensus was
>> > that
>> > it
>> > was now recognized as a worthless feature, but it did no harm
>> > (since
>> > it was
>> > optional), so leave it in for legacy compatibility.
>>
>> All of this is of virtually no relevance to the topic under discussion
>>
>> > There's some growing thought that even static type checking is an
>> > emperor
>> > without clothes, that dynamic type checking (like Python does) is
>> > more
>> > robust and more productive. I'm not at all convinced of that yet
>> > <g>,
>> > but
>> > it's fun seeing the conventional wisdom being challenged. It's good
>> > for all
>> > of us.
>>
>> I'm with you there.
>>
>> >> My position is simply that compile-time error detection is better
>> >> than
>> >> runtime error detection.
>> >
>> > In general, I agree with that statement. I do not agree that it is
>> > always
>> > true, especially in this case, as it is not necessarilly an error.
>> > It
>> > is
>> > hypothetically an error.
>>
>> Nothing is *always* true. That's kind of one of the bases of my thesis.
>>
>> >> Now you're absolutely correct that an invalid state throwing an
>> >> exception, leading to application/system reset is a good thing.
>> >> Absolutely. But let's be honest. All that achieves is to prevent a
>> >> bad
>> >> program from continuing to function once it is established to be
>> >> bad.
>> >> It
>> >> doesn't make that program less bad, or help it run well again.
>> >
>> > Oh, yes it does make it less bad! It enables the program to notify
>> > the
>> > system that it has failed, and the backup needs to be engaged. That
>> > can make
>> > the difference between an annoyance and a catastrophe. It can help
>> > it
>> > run
>> > well again, as the error is found closer to the the source of it,
>> > meaning it
>> > will be easier to reproduce, find and correct.
>>
>> Sorry, but this is totally misleading nonsense. Again, you're arguing
>> against me as if I think runtime checking is invalid or useless.
>> Nothing
>> could be further from the truth.
>>
>> So, again, my position is: Checking for an invalid state at runtime,
>> and
>> acting on it in a non-ignorable manner, is the absolute best thing
>> one
>> can do. Except when that error can be detected at runtime.
>>
>> Please stop arguing against your demons on this, and address my
>> point.
>> If an error can be detected at compile time, then it is a mistake to
>> detect it at runtime. Please address this specific point, and stop
>> general carping at the non-CP adherents. I'm not one of 'em.
>>
>> >> Depending
>> >> on the vaguaries of its operating environment, it may well just
>> >> keep
>> >> going bad, in the same (hopefully very short) amount of time,
>> >> again
>> >> and
>> >> again and again. The system's not being (further) corrupted, but
>> >> it's
>> >> not getting anything done either.
>> >
>> > One of the Mars landers went silent for a couple days. Turns out it
>> > was a
>> > self detected fault, which caused a reset, then the fault, then the
>> > reset,
>> > etc. This resetting did eventually allow JPL to wrest control of it
>> > back. If
>> > it had simply locked, oh well.
>>
>> Abso-bloody-lutely spot on behaviour. What: you think I'm arguing
>> that
>> the lander should have all its checking done at compile time (as if
>> that's even possible) and eschew runtime checking.
>>
>> At no time have I ever said such a thing.
>>
>> > On airliners, the self detected faults trigger a dedicated circuit
>> > that
>> > disables the faulty computer and engages the backup. The last,
>> > last,
>> > last
>> > thing you want the autopilot on an airliner to do is execute a
>> > return
>> > 0;
>> > some programmer threw in to shut the compiler up. An exception
>> > thrown,
>> > shutting down the autopilot, engaging the backup, and notifying the
>> > pilot is
>> > what you'd much rather happen.
>>
>> Same as above. Please address my thesis, not the more conveniently down-shootable one you seem to have addressing.
>>
>> >> It's clear, or seems to to me, that this issue, at least as far as
>> >> the
>> >> strictures of D is concerned, is a balance between the likelihoods
>> >> of:
>> >>     1.    producing a non-violating program, and
>> >>     2.    preventing a violating program from continuing its
>> >> execution
>> >> and, therefore, potentially wreck a system.
>> >
>> > There's a very, very important additional point - that of not
>> > enticing
>> > the
>> > programmer into inserting "shut up" code to please the compiler
>> > that
>> > winds
>> > up masking a bug.
>>
>> Absolutely. But that is not, in and of itself, sufficient
>> justification
>> for ditching compile detection in favour of runtime detection. Yet
>> again, we're having to swallow absolutism - dare I say dogma? -
>> instead
>> of coming up with a solution that handles all requirements to a
>> healthy
>> degree.
>>
>> >> You seem to be of the opinion that the current situation of
>> >> missing
>> >> return/case handling (MRCH) minimises the likelihood of 2. I agree
>> >> that
>> >> it does so.
>> >>
>> >> However, contrarily, I assert that D's MRCH minimises the
>> >> likelihood
>> >> of
>> >> producing a non-violating program in the first place. The reasons
>> >> are
>> >> obvious, so I'll not go into them. (If anyone's cares to disagree,
>> >> I
>> >> ask
>> >> you to write a non-trival C++ program in a hurry, disable *all*
>> >> warnings, and go straight to production with it.)
>> >>
>> >> Walter, I think that you've hung D on the petard of 'absolutism in
>> >> the
>> >> name of simplicity', on this and other issues. For good reasons,
>> >> you
>> >> won't conscience warnings, or pragmas, or even switch/function
>> >> decoarator keywords (e.g. "int allcases func(int i) { if i < 0
>> >> return -1'; }"). Indeed, as I think most participants will
>> >> acknowledge,
>> >> there are good reasons for all the decisions made for D thus far.
>> >> But
>> >> there are also good reasons against most/all of those decisions.
>> >> (Except
>> >> for slices. Slices are *the best thing* ever, and coupled with
>> >> auto+GC,
>> >> will eventually stand D out from all other mainstream
>> >> languages.<G>).
>> >
>> > Jan Knepper came up with the slicing idea. Sheer genius!
>>
>> Truly
>>
>> >> Software engineering hasn't yet found a perfect language. D is not
>> >> perfect, and it'd be surprising to hear anyone here say that it
>> >> is.
>> >> That
>> >> being the case, how can the policy of absolutism be deemed a
>> >> sensible
>> >> one?
>> >
>> > Now that you set yourself up, I can't resist knocking you down with
>> > "My
>> > position is simply that compile-time error detection is better than
>> > runtime
>> > error detection." :-)
>>
>> ?
>>
>> If you're trying to say that I've implied that compile-time detection
>> can handle everything, leaving nothing to be done at runtime, you're
>> either kidding, sly, or mental. I'm assuming kidding, from the
>> smiley,
>> but it's a bit disingenuous at this level of the debate, don't you
>> think?
>>
>> >> It cannot be sanely argued that throwing on missing returns is a
>> >> perfect
>> >> solution, any more than it can be argued that compiler errors on
>> >> missing
>> >> returns is. That being the case, why has D made manifest in its
>> >> definition the stance that one of these positions is indeed
>> >> perfect?
>> >
>> > I don't believe it is perfect. I believe it is the best balance of
>> > competing
>> > factors.
>>
>> I know you do. We all know that you do. It's just that many disagree that it is. That's one of the problems.
>>
>> >> I know the many dark roads that await once the tight control on
>> >> the
>> >> language is loosened, but the real world's already here, batting
>> >> on
>> >> the
>> >> door. I have an open mind, and willing fingers to all kinds of
>> >> languages. I like D a lot, and I want it to succeed a *very great
>> >> deal*.
>> >> But I really cannot imagine recommending use of D to my clients
>> >> with
>> >> these flaws of absolutism. (My hopeful guess for the future is
>> >> that
>> >> other compiler variants will arise that will, at least, allow
>> >> warnings
>> >> to detect such things at compile time, which may alter the
>> >> commercial
>> >> landscape markedly; D is, after all, full of a great many
>> >> wonderful
>> >> things.)
>> >
>> > I have no problem at all with somebody making a "lint" for D that
>> > will
>> > explore other ideas on checking for errors. One of the reasons the
>> > front end
>> > is open source is so that anyone can easily make such a tool.
>>
>> I'm not talking about lint. I confidently predict that the least
>> badness
>> that will happen will be the general use of non-standard compilers
>> and
>> the general un-use of DMD. But I realistically think that D'll
>> splinter
>> as a result of making the same kinds of mistakes, albeit for
>> different
>> reasons, as C++. :-(
>>
>> >> One last word: I recall a suggestion a year or so ago that would
>> >> required the programmer to explicitly insert what is currently
>> >> inserted
>> >> implicitly. This would have the compiler report errors to me if I
>> >> missed
>> >> a return. It'd have the code throw errors to you if an unexpected
>> >> code
>> >> path occured. Other than screwing over people who prize typing one
>> >> less
>> >> line over robustness, what's the flaw? And yet it got no traction
>> >> ....
>> >
>> > Essentially, that means requiring the programmer to insert:
>> >    assert(0);
>> >    return 0;
>>
>> That is not the suggested syntax, at least not to the best of my recollection.
>>
>> > It just seems that requiring some fixed boilerplate to be inserted
>> > means
>> > that the language should do that for you. After all, that's what
>> > computers
>> > are good at!
>>
>> LOL! Well, there's no arguing with you there, eh?
>>
>> You don't want the compiler to automate the bits I want. I don't want
>> it
>> to automate the bits you want. I suggest a way to resolve this, by
>> requiring more of the programmer - fancy that! - and you discount
>> that
>> because it's something the compiler should do.
>>
>> Just in case anyone's missed the extreme illogic of that position,
>> I'll
>> reiterate.
>>
>>     Camp A want behaviour X to be done automatically by the compiler
>>     Camp B want behaviour Y to be done automatically by the compiler.
>> X
>> and Y are incompatible, when done automatically.
>>     By having Z done manually, X and Y are moot, and everything works
>> well. (To the degree that D will, then, and only then, achieve
>> resultant
>> robustnesses undreamt of.)
>>
>>     Walter reckons that Z should be done automatically by the
>> compiler.
>> Matthew auto-defolicalises and goes to wibble his frimble in the back
>> drim-drim with the other nimpins.
>>
>> Less insanely, I'm keen to hear if there's any on-point response to this?
>>
>> >> [My goodness! That was way longer than I wanted. I guess we'll
>> >> still
>> >> be
>> >> arguing about this when the third edition of DPD's running hot
>> >> through
>> >> the presses ...]
>> >
>> > I don't expect we'll agree on this anytime soon.
>>
>> Agreed
>>
>>
>
> 


February 05, 2005
"Dave" <Dave_member@pathlink.com> wrote in message news:cu2uq3$288a$1@digitaldaemon.com...
>
> "Matthew" <admin@stlsoft.dot.dot.dot.dot.org> wrote in message news:cu1q0r$1609$1@digitaldaemon.com...
>>
>> "Vathix" <vathix@dprogramming.com> wrote in message news:opslo861ihkcck4r@esi...
>>>>> Guys, if we persist with the mechanism of no compile-time
>>>>> detection of
>>>>> return paths
>>>>
>>>> "and switch cases"
>>>>
>>>>> , and rely on the runtime exceptions, do we really think NASA
>>>>> would use
>>>>> D? Come on!
>>>>
>>>
>>> Would you fly to mars in debug mode?
>>
>> Well, to seriously answer your question: I think production code, at least for 'important commercial', should be shipped with contract programming enforcement on.
>>
>
> How about some middle ground?
>
> class Foo
> {
>    ...
>    invariant(X) // runs with debug=X
>    {
>        ...
>    }
>    int foo(int i)
>    in(Y) {}    // runs with debug=Y
>    out(Y) {}
>    body(Z) {} // "error: missing body { ... } after in or out" if
> debug=Y but not debug=Z
> }
>
> Then you could do this:
>
> dmd -O -inline -release -debug=X -debug=Y foo.d  (-release and -debug are mutually exclusive, but not -release and -debug=ident)

If you mean that we should be able to individually select on/off the components of CP, i.e. preconditions, postconditions and invariants.

At first blush, I'd say yes. But I think this should take some thinking about, as there may be good reasons against that don't immediately spring to mind.

Oh, no, I see. You mean mix CP constructs with version. I'd say no, I think this is _too_ much flexibility. In the rare cases where people really need to have some class's constructs versioned, I think version would suffice. (That'd require that body can be supplied without in or out. I don't know if that's currently legal, but it should be.)

> Would it make sense in the commercial world where PwC is used (like your last project, Matthew)?

I'd say probably not. In this last large project, I did consider having a more granular approach, but the components run with ample speed anyway. The specific constructs which are 'purely debug', are left as simple debug-time asserts ACME_ASSERT / ACME_MESSAGE_ASSERT, while the CP constructs are ACME_ASSERT_PRECONDITION, ACME_ASSERT_POSTCONDITION, ACME_ASSERT_INVARIANT.

Now this does raise the question of whether/how we discriminate between CP constructs that we want moderated with the "-contracts=on/off" flag and those with the "-debug" flag. In my recent experience, I would say that it's *very important* to be able to both types, and control them separately. But that's going to require a new keyword, since people will not be willing to pepper their code with debug { ... } blocks.

Walter, your thoughts?


February 05, 2005
> I come from the position that a compiler's job (a part from
> compiling), is
> to help the coder write correct programs. Of course, it can't do this
> to
> the Nth degree because how does the compiler 'know' what is correct or
> not?
> However, a compiler is often able to detect things that are *probably*
> incorrect or have a high probability to cause the application to
> function
> incorrectly. Thus I see think that a good compiler is one that is
> allowed
> to have the ability to point these situations out to the code writer.
> (The
> compiler should also allow coders to tell the compiler that the coder
> knows
> what they are doing in this instance and just let me get on with it,
> okay?!)
>
> Now, what to do though if the code writer chooses to ignore the
> compiler's
> observations? I would suggest that the compiler should insert run time
> code
> that prevents the application from continuing if the application tries
> to
> continue past the code that the compiler thinks might ( i.e. highly
> likely)
> cause bad results.
>
> You seem to be concerned that a code will always insert 'dead code'
> just so
> the compiler will stop nagging them. Of course, some coders are just
> this
> immature. They either grow up or whither. As a coder matures, they
> will
> begin to take the compiler seriously and add in code that makes sense
> in
> the context.
>
> I'm 50 years old and I've been coding for 28 years. You will often
> find in
> my code such things as ...
>
>  Abort("Logic Error #nnn. If you see this, a mistake was made by the
> programmer. This should never be seen. Inform your supplier about this
> message.");

He he! Great stuff

> You might regard this is superfluous 'dead code', however a 'nice'
> message
> from the coder to the user is better than a compiler generated
> 'jargon'
> message that the user must decode. Thus my switch constructs always
> have a
> default clause, and any 'if' statement in which an unhandled false
> would
> cause problems, I have an 'else' phrase. I always have a return
> statement
> at the end of my function text, even if its will never be executed (if
> all
> goes well). Call it overkill if you like, but in the long run, it
> keeps the
> users better informed and *more* importantly, keeps future maintainers
> aware of the previous coder's intentions and reasons for doing things.
>
> Currently, D is way too dogmatic and unreasonably unhelpful to the coder.
>
> It is mostly still better than C/C++ though.

It is indeed mostly better. Unfortunately, in the ways in which it is not better it is disconcertingly flawed.

I've been involved with D for nearly three years now, and I've yet to meet a client who doesn't have use-preventing reservations about it. Though a big fan of D, and a hoper for its future, I myself do not use it for anything serious.






February 05, 2005
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Matthew schrieb am Sun, 6 Feb 2005 07:08:19 +1100:
> I just think that we should have CP and debug/release somewhat independent.
>
> Ideally, I'd like
>
>     "-debug" to have debugging info _and_ CP
>     "-release" to have CP
>     "-release -contracts=off" to have neither
>
> and, if anyone's that perverse
>
>     "-debug -contracts=off" to have debugging info only
>
> This all seems eminently straightforward. The only 'twist' is that CP is on by default, unless one explicitly requests it to be off. (I'm sure we can now start a heated battle about that ...)

How about using GDC having a look at
d/dmd/mars.h -> Param.useAssert|useInvariants|useIn|useOut|useArrayBounds|useSwitchError|useUnitTests
d/d-lang.cc -> opt_code , d_handle_option

Thomas


-----BEGIN PGP SIGNATURE-----

iD8DBQFCBURl3w+/yD4P9tIRAmfoAJ9VpNNbQO5ArPy8buyJfeyGsjiWZwCgnILL
94OisNSbPmTTocUz0qXFjf8=
=4wnf
-----END PGP SIGNATURE-----
February 05, 2005
"Matthew" <admin@stlsoft.dot.dot.dot.dot.org> wrote in message news:cu3a23$2iuq$1@digitaldaemon.com...
>
> "Dave" <Dave_member@pathlink.com> wrote in message news:cu2uq3$288a$1@digitaldaemon.com...
>>
>> "Matthew" <admin@stlsoft.dot.dot.dot.dot.org> wrote in message news:cu1q0r$1609$1@digitaldaemon.com...
>>>
>>> "Vathix" <vathix@dprogramming.com> wrote in message news:opslo861ihkcck4r@esi...
>>>>>> Guys, if we persist with the mechanism of no compile-time detection
>>>>>> of
>>>>>> return paths
>>>>>
>>>>> "and switch cases"
>>>>>
>>>>>> , and rely on the runtime exceptions, do we really think NASA would
>>>>>> use
>>>>>> D? Come on!
>>>>>
>>>>
>>>> Would you fly to mars in debug mode?
>>>
>>> Well, to seriously answer your question: I think production code, at least for 'important commercial', should be shipped with contract programming enforcement on.
>>>
>>
>> How about some middle ground?
>>
>> class Foo
>> {
>>    ...
>>    invariant(X) // runs with debug=X
>>    {
>>        ...
>>    }
>>    int foo(int i)
>>    in(Y) {}    // runs with debug=Y
>>    out(Y) {}
>>    body(Z) {} // "error: missing body { ... } after in or out" if debug=Y
>> but not debug=Z
>> }
>>
>> Then you could do this:
>>
>> dmd -O -inline -release -debug=X -debug=Y foo.d  (-release and -debug are mutually exclusive, but not -release and -debug=ident)
>
> If you mean that we should be able to individually select on/off the components of CP, i.e. preconditions, postconditions and invariants.
>
> At first blush, I'd say yes. But I think this should take some thinking about, as there may be good reasons against that don't immediately spring to mind.
>
> I'd say probably not. In this last large project, I did consider having a more granular approach, but the components run with ample speed

I think you're right. What I mentioned above would tie PwC too closely to debug(...) and also potentially complicate large projects greatly, by allowing too much granularity.

I'm with what you and Charlie posted earlier, some kind of -contracts=[on,off] flag or some such that could be used to override what -debug and -release both enforce now.

I'm currently thinking that the defaults should perhaps act the same as-is ('-debug' implies '-contracts=on'; '-release' implies '-contracts=off') because that is what current D users have come to expect and also because PwC is generally considered to be "debug" related (in other words, I think those defaults would be more intuitive for the majority of people familiar with PwC, but of course I could be wrong).

- Dave