The edited Wikipedia text for D is so far correct, even though the whole
page is not quite as precise as it could be. The theoretical basis and
the practical application are somewhat mixed. Fixing that, however,
would be a major task.
I think the fundamental distinction between three concepts is essential
in understanding the issue:
* exceptions - handling of run-time conditions caused by user, file,
network or any other kind of input. Hitting an exception is not a bug
but a regular function of the code.
* contracts - well designed parts of interfaces. Best understood
literally as "contract", defining who is responsible for a bug. The
possibility to check a contract at runtime is actually a secondary function.
* assertions - best understood as "comments" that can be checked by the
compiler. Sprinkle them freely wherever you find some non-trivial
relation between variables of the code.
I guess this whole issue simply is something that has to be discussed
more frequently to make people aware of it.
Greetings,
Norbert
bearophile wrote:
Norbert Nemec:
No! No! No! Design-by-contract means that it is the application's duty
to make sure that argument values are correct. If the program is
correct, the library can trust that the argument values are correct and
does not need to do checks. This is exactly the same situation that
assertions are for: Double-checking something to catch potential bugs.
Exceptions are a very different issue and should never be used for this
purpose.
A library interface simply is something different than a user interface.
Thank you, now I have understood what you mean (I did't understand your first
answer to me).
So you are saying that Contract Programming is not meant to be used to test for
wrong inputs coming from the user interface (just like asserts). I think you
are right, it is something that needs to be known. I think Michiel Helvensteijn
was saying something similar.
Then the D code in that Wikipedia page
(http://en.wikipedia.org/wiki/Class_invariant#D ) may need to be modified again.
Yet, if you note in the Java code there are extra if tests (that are not
present in the Eiffel code):
/*@
@requires 1<=d && d <=31;
@ensures day == d;
@*/
public void setDay(int d) {
if (1 <= d && d <= 31)
day = d;
}
Maybe that Java programmer doesn't trust the programmer, and thinks that class
can receive code from an user interface. Maybe because the D library uses
Contract programming, while the application code does not. What I think you are
missing is that there's difference between what's the theoretically correct
thing to do, and what's better to do in real code today (for example to avoid
certain bugs).
I am not sure how to write code yet, I'll need practice, and what I have just
said can be stupid. But now I understand what's right and why, thanks to this
useful discussion. I have never used Contract programming in my past languages,
and I have never read books about it, so I didn't know how to use it beside
knowing the D syntax to use it. I hope Andrei's book will have some pages about
this too, because it's a built-in part of D.
Bye,
bearophile