Contracts or Exceptions?

Kai Meyer kai at unixlords.com
Tue Mar 29 15:40:18 PDT 2011


On 03/29/2011 12:40 PM, Mike Linford wrote:
> Hello,
>
> So I'm writing a function for a library. It takes a struct as an
> argument. The struct's fields can't just be any old values, though. The
> function won't work if some of the fields are weird. It could return an
> erroneous value, or even crash.
>
> The thing is, though, that I can't tell whether the best approach is to
> use an in-contract or throw an exception if it doesn't pass my test. What
> would you guys recommend?
>
>
>

I was given two words of advice on exceptions:
"Use exceptions for the exceptional"
"Use exceptions only for the exceptional"

Meaning, if you expect something to fail frequently, using a try/catch 
is much more expensive than an if/else. "The exceptional" is something 
that should rarely ever occur, like running out of memory.

For contracts, they are usually meant as a developer tool to warn them 
when that they will be in no-man's land if they attempt to proceed any 
further. They are, therefore, not compiled in when you pass the D 
compiler the -release flag.

I don't think that contracts and exceptions are mutually exclusive. They 
provide two different safeguards. One is a tool to aid in the 
development process, one is a tool to safeguard against exceptional 
run-time scenarios.

However, I think if I rephrase your question a little bit, it might 
provide you what I think you're after. I'm making an assumption here, so 
I may be way off the mark.

"Who's responsibility is it to check whether or not the data passed into 
the function is valid? Should I accept whatever the user wants to pass 
in, and let them know when it's invalid, or should I trust that the user 
is sending in good data?"

I think that's a choice for you to make. Contract programming is often 
used to put the burden of validation on the user of the library (meaning 
programmer writing software taht uses your library). Exceptions could be 
used to indicate that the library writer is accepting responsibility for 
validating the data before using it.

But validating data is not the only reason to use exceptions, and it's 
not unusual for a library to skip all validations and force the user to 
do all the checking before hand. Arrays are a good example. When not in 
-release mode, array boundaries are checked upon every access to the 
array, and an exception is thrown if access goes out of bounds. In 
-release mode, if you go out of bounds you get a segfault. This is one 
example of giving the user (programmer) of arrays the responsibility to 
check boundaries so that the library can focus on being fast.

I think the choice comes down to a balance between performance, 
responsibility, and maintainability. (Oh, and you'll usually get it 
wrong the first time, so don't be sad.)


More information about the Digitalmars-d-learn mailing list