www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Contracts + Assert

reply Mike Linford <sgtmuffles myrealbox.com> writes:
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?
Oct 30 2007
parent reply Ary Borenszweig <ary esperanto.org.ar> writes:
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.
Oct 30 2007
parent reply Mike Linford <sgtmuffles myrealbox.com> writes:
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.

Oct 30 2007
next sibling parent reply Daniel Keep <daniel.keep.lists gmail.com> writes:
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?

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.


Oct 30 2007
next sibling parent "Jarrett Billingsley" <kb3ctd2 yahoo.com> writes:
"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.
Oct 31 2007
prev sibling parent Bruno Medeiros <brunodomedeiros+spam com.gmail> writes:
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
Nov 03 2007
prev sibling next sibling parent Lutger <lutger.blijdestijn gmail.com> writes:
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.
Oct 31 2007
prev sibling parent BCS <BCS pathlink.com> writes:
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.)
Oct 31 2007