Thread overview
Contracts + Assert
Oct 31, 2007
Mike Linford
Oct 31, 2007
Ary Borenszweig
Oct 31, 2007
Mike Linford
Oct 31, 2007
Daniel Keep
Nov 03, 2007
Bruno Medeiros
Oct 31, 2007
Lutger
Oct 31, 2007
BCS
October 31, 2007
I'm a bit confused about why it seems to be advocated that only assert()'s be used in contracts. Why is it that more specific exceptions aren't thrown instead? Wouldn't this make debugging easier?
October 31, 2007
Mike Linford escribió:
> I'm a bit confused about why it seems to be advocated that only assert()'s be used in contracts. Why is it that more specific exceptions aren't thrown instead? Wouldn't this make debugging easier?

Contracts are a way to ensure that the program is working as expected, and it is used as expected.

For example, if an assert in an "in { }" section fails, that means the some wrong parameter was passed to the function. It was a programmer's error: either she mistyped something, or she don't understand it's usage. If the "out { }" fails, the function's logic is wrong (or the "out" :-P).

For an invariant, if it fails, it's a problem in the class' logic.

If I remember correctly, assertion failures do throw an AssertError exception, but these exceptions aren't supposed to be catched (if the program's logic is wrong, the only way to recover from that exception is by changing the program itself). In fact, contracts are removed at all if you compile in -release mode.
October 31, 2007
So in what cases would one prefer to use contracts over normal exception handling?

Ary Borenszweig Wrote:

> Mike Linford escribió:
> > I'm a bit confused about why it seems to be advocated that only assert()'s be used in contracts. Why is it that more specific exceptions aren't thrown instead? Wouldn't this make debugging easier?
> 
> Contracts are a way to ensure that the program is working as expected, and it is used as expected.
> 
> For example, if an assert in an "in { }" section fails, that means the some wrong parameter was passed to the function. It was a programmer's error: either she mistyped something, or she don't understand it's usage. If the "out { }" fails, the function's logic is wrong (or the "out" :-P).
> 
> For an invariant, if it fails, it's a problem in the class' logic.
> 
> If I remember correctly, assertion failures do throw an AssertError exception, but these exceptions aren't supposed to be catched (if the program's logic is wrong, the only way to recover from that exception is by changing the program itself). In fact, contracts are removed at all if you compile in -release mode.

October 31, 2007

Mike Linford wrote:
> So in what cases would one prefer to use contracts over normal exception handling?

This, my friend, is the $60,000,000,000 question, and something I've struggled with myself.

The problem is that almost any rule you come up with ends up being applicable to both contracts and in-function exceptions.

Another issue is that asserts disappear when you throw -release.  Now, the idea that you can remove the "training wheels" when the program is debugged is nice in theory, but how many pieces of software do you know that do not have a *single* bug in them?  What's more, if there is a bug that your asserts haven't caught in normal testing, odds are it's an obscure, hard to find bug.  If that's the case, the last thing you want to do is remove the asserts, as they're your best tool for figuring out what's gone wrong.  A debugger doesn't count because you can't really ask a user to start up your program inside one.

For me, I'll likely be one of those people who uses contracts all over the place, and never uses the -release switch.  In that scenario, contracts are useful for distinguishing interface-checking code (like making sure arguments are within range, etc.) from more general stuff (like making sure operations succee.)

In the end, it's really up to personal choice.

	-- Daniel

> Ary Borenszweig Wrote:
> 
>> Mike Linford escribi�:
>>> I'm a bit confused about why it seems to be advocated that only assert()'s be used in contracts. Why is it that more specific exceptions aren't thrown instead? Wouldn't this make debugging easier?
>> Contracts are a way to ensure that the program is working as expected, and it is used as expected.
>>
>> For example, if an assert in an "in { }" section fails, that means the some wrong parameter was passed to the function. It was a programmer's error: either she mistyped something, or she don't understand it's usage. If the "out { }" fails, the function's logic is wrong (or the "out" :-P).
>>
>> For an invariant, if it fails, it's a problem in the class' logic.
>>
>> If I remember correctly, assertion failures do throw an AssertError exception, but these exceptions aren't supposed to be catched (if the program's logic is wrong, the only way to recover from that exception is by changing the program itself). In fact, contracts are removed at all if you compile in -release mode.
> 
October 31, 2007
"Daniel Keep" <daniel.keep.lists@gmail.com> wrote in message news:fg93ci$1plr$1@digitalmars.com...

> This, my friend, is the $60,000,000,000 question, and something I've struggled with myself.

I see expensive questions have also felt the effects of inflation.  ;)

> The problem is that almost any rule you come up with ends up being applicable to both contracts and in-function exceptions.
>
> Another issue is that asserts disappear when you throw -release.  Now, the idea that you can remove the "training wheels" when the program is debugged is nice in theory, but how many pieces of software do you know that do not have a *single* bug in them?  What's more, if there is a bug that your asserts haven't caught in normal testing, odds are it's an obscure, hard to find bug.  If that's the case, the last thing you want to do is remove the asserts, as they're your best tool for figuring out what's gone wrong.  A debugger doesn't count because you can't really ask a user to start up your program inside one.
>
> For me, I'll likely be one of those people who uses contracts all over the place, and never uses the -release switch.  In that scenario, contracts are useful for distinguishing interface-checking code (like making sure arguments are within range, etc.) from more general stuff (like making sure operations succee.)

This is why I think there needs to be more granularity in the compiler options.  If you look at the DMD source, you'll see that the compiler has separate options for assert, invariants, in, out, array bounds, and "switch without a default," but -debug and -release enable or diable them all as a chunk.  All that has to happen is for them to be split into multiple switches, so we can turn off some stuff but leave asserts or something.


October 31, 2007
Mike Linford wrote:
> So in what cases would one prefer to use contracts over normal exception handling?

In theory, violation of contracts mean a program has a bug and exceptions may signify an exceptional circumstance, but never a bug. This should or could be useful for understanding the nature of the problem and implementing checks during development that are too costly in a released product.

October 31, 2007
Mike Linford wrote:
> So in what cases would one prefer to use contracts over normal exception handling?
> 
> Ary Borenszweig Wrote:
> 
> 


the rule I use is use assert when you are checking something that should not happen (e.i. If this happens there *is* a coding error) use throw for things that might happen if something external is wrong (e.i. bad user input, no Internet connection, out of disk space, bad file name etc.)
November 03, 2007
Daniel Keep wrote:
> 
> Mike Linford wrote:
>> So in what cases would one prefer to use contracts over normal exception handling?
> 
> This, my friend, is the $60,000,000,000 question, and something I've
> struggled with myself.
> 

Here is good article on the subject:

http://www.artima.com/cppsource/deepspace.html


-- 
Bruno Medeiros - MSc in CS/E student
http://www.prowiki.org/wiki4d/wiki.cgi?BrunoMedeiros#D