Article Discussion
Contract Programming 101
Summary: Contract Programming is something that�s been around for a long time but is getting far more air play, and rigorous examination, in recent times. Despite general agreement regarding the attraction of software contracts to programmers (and users!), there remains equivocation on what to do when contracts are broken. This is Part One of a series that takes a slightly philosophical look at this important issue, considers the tradeoffs between information and safety in reacting to contract violations, looks at practical measures for shutting errant processes, and introduces a new technique for the implementation of unrecoverable exceptions in C++.
19 posts on 2 pages.      
« Previous 1 2 Next »
The ability to add new comments in this discussion is temporarily disabled.
Most recent reply: January 25, 2006 4:05 AM by
Chuck
Posts: 32 / Nickname: cda / Registered: February 11, 2003 0:06 PM
Contract Programming 101
December 31, 2005 9:00 PM      
This is Part One of a series that takes a slightly
philosophical look at contract programming, considers the tradeoffs between information and safety in reacting to contract violations, looks at practical measures for shutting errant processes, and introduces a new technique for the implementation of unrecoverable exceptions in C++.

http://www.artima.com/cppsource/deepspace.html
Harrison
Posts: 7 / Nickname: hxa7241 / Registered: April 10, 2005 7:41 AM
Re: The Nuclear Reactor and The Deep Space Probe
January 2, 2006 10:44 AM      
Contracts work at a particular level. They do not check:
* if memory is faulty -- that is a hardware matter
* if variables are of the correct type -- that is a type-system matter
* if class axioms hold -- that is a testing matter
* if use cases are fulfilled -- that is a requirements matter
Contracts check abstractions. An abstraction holds a variable value within a fixed schema. A contract checks that schema is properly fixed. Since abstractions are defined during design, and the values at runtime, it follows that contracts are concerned with design.

One corollary is that if the parameters to a method are of properly defined types, then pre/post-condition checks are superflous. The validity of the types guarantees the conditions. Not all method parameters are conveniently/practically expressed like this though.

Why check invariants at the beginning *and* end of a method? There is an obvious redundancy. Meyer points out that this is needed with mulithreaded software. But if you like an easy life you will be avoiding multithreading and it rarely applies. So invariant checks are only needed in non-const methods, at the end, and before self-calls.

It is going too far to check invariants against "some other part of the processing tramping on its memory". If something else has free access to the object through a pointer, then either: encapsulation has not been secured somewhere -- and *that* part of the design needs addressing. Or whatever else owns that pointer is behaving faultily -- and that's a failure of *its* class invariant checking. Either way, the cautionary code should be local, not spread across all other code in the program. It's part of the modularisation.
cdiggins
Posts: 21 / Nickname: cdiggins / Registered: February 4, 2004 1:54 PM
Re: The Nuclear Reactor and The Deep Space Probe
January 2, 2006 1:35 PM      
> It is going too far to check invariants against "some
> other part of the processing tramping on its memory".

In C/C++ designs lacking proper encapsulation are common and sometimes even neccessary for performance reasons. Theoretically your arguments appear to me to be sound, however in real-world scenarios C++ programming is rarely theoretical ideal. Constness can be easily violated, memory is often overwritten. There is no reason that I can see to not use contracts to help detect these kinds defects.
Radek
Posts: 7 / Nickname: radek / Registered: December 20, 2005 11:23 PM
Re: Contract Programming 101
January 3, 2006 5:53 AM      
> Contract violations are not exceptional conditions

There is lots of different definitions about what exceptional conditions are. Languages such as Java and C/C++ don't provide a mechanism to handle multiple mutually exclusive outcomes of method or function calls comfortably. Due to this lack, what I see is, that programmers use the language construct "exception" as a tool to signal a certain outcome out of a set of possible outcomes to the caller. Handcoded alternatives, such as using return values for the signalling of a specific outcome are rather awkward to handle and have no compiler support. But that means: using an exception in Java or C++ does not automatically imply there is an exceptional condition! Instead, these are return values. That is why such "kind of exceptions" are used in control flow.

When making such a conscious distinction between using exceptions as a replacement for return values and using exceptions, well, for exceptional conditions, then I very well opt for contract violations being exceptional conditions.

> And if you're still sceptical whether exceptions may be part of a function's contract, consider the case of the operator new() function. If throwing an instance of bad_alloc (or something derived from bad_alloc) were not within its contract, it would mean that memory exhaustion - a runtime condition largely outside the control of the program designer - would be a contract violation,

If an exception is part of a function's contract then it is nothing different from a return value. This usage of exceptions is widely adopted to cope with multiple mutually exclusive outcomes. But it then is not really an "exception" anymore.
Might it be, that "real" exceptions are exceptions because they exactly are not part of the functions contract?
cdiggins
Posts: 21 / Nickname: cdiggins / Registered: February 4, 2004 1:54 PM
Re: Contract Programming 101
January 3, 2006 6:01 AM      
> This usage of
> exceptions is widely adopted to cope with multiple
> mutually exclusive outcomes. But it then is not really an
> "exception" anymore.

I beg your pardon, but that doesn't make any sense. Perhaps an exception is not an error, but an exception is always an exception!
Radek
Posts: 7 / Nickname: radek / Registered: December 20, 2005 11:23 PM
Re: Contract Programming 101
January 3, 2006 6:28 AM      
> I beg your pardon, but that doesn't make any sense.
> Perhaps an exception is not an error, but an exception is
> always an exception!

There is the language construct/mechanism "exception". And then there is the word "exception". What I mean is, you can use the language construct "exception" for a situation that is not exceptional in the sense of the word "exception".

I tried to point out, that many programmers use the exception mechanism as a replacement for return values where the function has multiple mutually exclusive outcomes. I don't see why one outcome out of a set of possible outcomes should be superiour or inferior to the others (and thus "exceptional"). So, when using the language construct exceptions in such a sense, there is nothing "exceptional" about them at all.

An example for multiple mutually exclusive outcomes: function to execute a transfer between banking accounts. Possible outcomes:

1. transfer finished

2. account A does not exist

3. account B does not exist

4. account A is not covered

5. ...

Now, is (2) an exceptional situation or an expected outcome?

It depends on the contract. If the contract says, I will tell you if account A does not exist, then it is an expected outcome, not an exceptional situation. If the contract says nothing about account A then account A not existing is an exceptional situation.
Roland
Posts: 25 / Nickname: rp123 / Registered: January 7, 2006 9:42 PM
Input validation vs. Precondition
January 8, 2006 3:26 AM      
"Contract Violations are Not Invalid Input Data" but your Precondition checks are called IsVALIDReadableString() or IsDateVALID(). The distinction between Preconditon and Input Validation is unclear in your description (and in general in all texts I've read so far).
I appreciate that you try to put Contract Programming in C++ into a conceptual frame but the notions of C.P. are so ambiguous and arbitrarily interpretable that I doubt it's worth the effort.
Vladimir
Posts: 4 / Nickname: robotact / Registered: August 27, 2005 2:15 AM
Re: Contract Programming 101
January 9, 2006 0:19 PM      
> There is the language construct/mechanism "exception". And
> then there is the word "exception". What I mean is, you
> can use the language construct "exception" for a situation
> that is not exceptional in the sense of the word
> "exception".
No, generally you can't. Problem is, laguages unambiguously state that exception is something exceptional and therefore most implementations optimize based on this assumption - in addition to the fact that exceptions are not that obvious to implement efficiently. You may have 100x or 1000x penalty if you use, say, exception instead of return value.
Radek
Posts: 7 / Nickname: radek / Registered: December 20, 2005 11:23 PM
Re: Contract Programming 101
January 10, 2006 2:30 AM      
> No, generally you can't. Problem is, laguages
> unambiguously state that exception is something
> exceptional and therefore most implementations optimize
> based on this assumption - in addition to the fact that
> exceptions are not that obvious to implement efficiently.
> You may have 100x or 1000x penalty if you use, say,
> exception instead of return value.
Yes, thank you, I am very aware of the possible performance penalty. While I said "you can" I didn't mean you should (even the performance penalty set aside). What I see is that many APIs (at least in Java) do. They use an exception where a return value would be more appropriate (not only for performance reasons, mainly for contract definition ones!). They do it because the exception mechanism offers a more convenient (read: less typing) way to signal and handle multiple mutually exclusive outcomes of a method call when compared to fiddling around with return values.

In this sense my original post tried to pinpoint the ambiguity in the authors statement that "exceptions may be part of the contract". If exceptions are not used as a replacement for return values, then they just can't be part of the contract. I feel a need for clarification in that "exceptions may be part of the contract", iff used as a replacement for return values, but may never be part of the contract otherwise.
Thorsten
Posts: 4 / Nickname: nesotto / Registered: December 10, 2003 1:42 AM
Re: Contract Programming 101
January 10, 2006 9:31 AM      
> In this sense my original post tried to pinpoint the
> ambiguity in the authors statement that "exceptions may be
> part of the contract". If exceptions are not used as a
> replacement for return values, then they just can't
> be part of the contract. I feel a need for clarification
> in that "exceptions may be part of the contract", iff used
> as a replacement for return values, but may never be part
> of the contract otherwise.

I would say that they are *always* part of the contract.

Even if an exception is not used as a return-value, the state of the object just before exception is throw may be specified. It is a variant of a post-condition where you give additional guarantees if certain exceptions are thrown.

Some tools use the pseudo-keyword "exsure" for this.

-Thorsten
Radek
Posts: 7 / Nickname: radek / Registered: December 20, 2005 11:23 PM
Re: Contract Programming 101
January 11, 2006 1:50 AM      
> Even if an exception is not used as a return-value, the
> state of the object just before exception is throw may be
> specified.

To repeat you in my own words: The contract defines to throw a certain exception if the object reaches a specified state. Is this correct? This raises a question: How is this different from a contract defining to return a certain value if the object reaches a specified state? In other words: Why do you think this proposed usage of exceptions is not just another example of replacing return values by exceptions?

> It is a variant of a post-condition where you
> give additional guarantees if certain exceptions are
> thrown.

I don't think that enforcement of contract conditions should become part of the function or method interface (and, therefore, extending it as a side effect). Rather, this enforcement takes place on a higher level, unknown to the fundamental application code (exceptions on contract violations, yes, but not part of a interface or contract).
Max
Posts: 18 / Nickname: mlybbert / Registered: April 27, 2005 11:51 AM
About abusing exceptions
January 11, 2006 10:12 AM      
/* [original] What I mean is, you can use the language construct "exception" for a situation that is not exceptional ...

[response] No, generally you can't.
*/

Generally you shouldn't, but I'm not aware of any language that prevents you from abusing the exception system.

Consider:

void function(int x)
{ throw x;
};

Very bad idea. Even so, the language won't stop me from doing this.
Max
Posts: 18 / Nickname: mlybbert / Registered: April 27, 2005 11:51 AM
Re: Contract Programming 101
January 11, 2006 10:18 AM      
/* To repeat you in my own words: The contract defines to throw a certain exception if the object reaches a specified state. Is this correct?
*/

The original article said "Contracts *may* be enforced in other ways, e.g. via exceptions ..." (emphasis added).

The reason for using exceptions to enforce contracts is simple -- the preconditions/postconditions/invariants must hold for the function to be able to do anything reasonable. If they don't hold, by definition the function can't do anything reasonable. Depending on the function signature, it may not be possible to return a good error code, but it's always possible to abort and throw.

Then people have to get used to watching for exceptions. But they may not remember to watch for error codes. There's a reason that Perl programmers are encouraged to die on error instead of returning error codes. I like error codes in the tradition of C, but I don't like return codes that are overloaded like fork()'s.
Thorsten
Posts: 4 / Nickname: nesotto / Registered: December 10, 2003 1:42 AM
Re: Contract Programming 101
January 16, 2006 2:49 PM      
> > Even if an exception is not used as a return-value, the
> > state of the object just before exception is throw may
> be
> > specified.
>
> To repeat you in my own words: The contract defines to
> throw a certain exception if the object reaches a
> specified state. Is this correct?

The contract may not when the exception is thrown, or that condition may not be easily expressed. However, irrelevant of when or why the exception is thrown, the function may guarantee, as part of its contract, that certain parameters (eg. the implicit this pointer in member functions) are left in a certain state.

As an example, look at exception-safety guarantees. If your function provides the basic guarantee, it promises that the invariant holds if an exception is thrown. It doesn't state when the exception is thrown or why.

Now the contract might be much more specific that that, maybe you can guarantee that X.foo() returns true too.

> This raises a question:
> How is this different from a contract defining to return a
> certain value if the object reaches a specified state? In
> other words: Why do you think this proposed usage of
> exceptions is not just another example of replacing return
> values by exceptions?

I feel that I don't have a good understanding of your definition of when exception are not used as return values.
Maybe you can elaborate.

-Thorsten
Radek
Posts: 7 / Nickname: radek / Registered: December 20, 2005 11:23 PM
Re: Contract Programming 101
January 18, 2006 1:31 AM      
> I feel that I don't have a good understanding of your
> definition of when exception are not used as return
> values.
> Maybe you can elaborate.

I will try to. Pls give me 2-3 days, I'm currently heavily involved.
19 posts on 2 pages.
« Previous 1 2 Next »