Good Contract programming idiom?

bearophile bearophileHUGS at lycos.com
Tue Mar 2 10:42:44 PST 2010


dsimcha:

>In D2, isn't that what enforce() is for?<

You are probably right :-)
Have Andrei design part of the standard library is not enough, I also have to understand why the idioms it encourages are good :-) Now I have understood what enforce is useful for (as a shortcut for a test+throw), but I prefer enforceEx() that allows me to choose the right exception too.
Reading the whole source code of Phobos is not enough, I don't uderstand still why and where std.contracts.pointsTo and std.contracts.assumeSorted can be useful.
AssumeSorted() can even leave a "sorted" bit set somewhere inside the array.
std.contracts.assumeUnique is not integrated with the type system, so it less useful.

----------------------

Lutger:

>Theoretically exceptions are situations you expect can happen, even though the code is bug free, while assertions always indicate a bug.<

OK.


>your development version of your software can run very slow, it's usually no problem. With easy way to compile out assertions, you are more inclined to use them liberally.<

D has debug levels too, so you can put more costly tests at a layer 2 and all the other tests at the layer 1. So most debug builds can be fast enough.


>Then there is the case where you want to leave some 'assertion checks' in release mode too, like you mention. Ideally you may want something that throws AssertError when compiled in debug mode and InvalidArgumentException in release mode.<

This can be done just keeping asserts in the precondition, and putting the exceptions in the body (if you are a really tidy person you can even disable the exceptions in not release built).
But in practice I think the "good enough" thing to do is to be sure essential precontions are met, and stop the code otherwise.

------------------

Michiel Helvensteijn:

>But I suspect these exceptions are not supposed to be caught, and are only used as makeshift release mode assertions.<

You are probably right.
enforce() or enforceEx() are probably meant to become the idiomatic way to write such asserts that acts as exceptions. Maybe they can be replaced by special future asserts that can't be disabled :-)


>That's not nice. Preconditions are part of the public interface, and D should treat them better. Even in release mode, I'd want to keep the runtime checks, except if we have static proof of total correctness at every call site, in which case runtime checks are redundant. If the programmer is deadset on removing runtime checks for unproven assertions, he should have to compile with the --dangerous-unchecked-assertions flag.<

Current D compilers generally don't remove asserts statically thanks to proofs. Future D compilers can learn to do this better (and at that point I agree that removing the preconditions from the code as in that Wikipedia page will be bad).
I think most D programmers today want to remove runtime checks for unproven assertions, that's the point of the -release compile flag.
SafeD modules can keep the asserts.
With the LDC compiler you have a finer control of what tests to disable (only contracts, nornal asserts, array bounds, etc).
With the current DMD compiler and current usages of D I think what's written in that Wikipedia page is better.

Thank you for all the answers,
bye,
bearophile



More information about the Digitalmars-d mailing list