View mode: basic / threaded / horizontal-split · Log in · Help
February 04, 2012
Contracts vs debug
Why/where should I use contracts vs debug statements? Is it 
completely arbitrary? If so, I wonder if contracts syntax is even 
needed:

   int foo(int bar)
   in
   {
       assert(bar != 0);
   }
   body
   {
       return bar + 1;
   }

The thing I like more about debug statements, is that I can put 
them anywhere in my code, testing parameters and locals in the 
same way. If "for documentation" is the only argument for 
contracts, I find that a bit weak.

   int foo(int bar)
   {
       debug assert(bar != 0);

       return bar + 1;
   }

That is much cleaner syntax and just as easy to understand from a 
assertion-failure/documentation standpoint IMO.
February 04, 2012
Re: Contracts vs debug
F i L:

> Why/where should I use contracts vs debug statements?

This is a sting point:
http://en.wikipedia.org/wiki/Design_by_contract

Contract-based programming is a different way to write programs. But adding few more asserts here and there is useful still.


>     int foo(int bar)
>     {
>         debug assert(bar != 0);

Asserts go away with -release. So generally I don't need to write that.

Bye,
bearophile
February 04, 2012
Re: Contracts vs debug
On 02/04/2012 06:18 PM, F i L wrote:
> Why/where should I use contracts vs debug statements? Is it completely
> arbitrary? If so, I wonder if contracts syntax is even needed:
>
> int foo(int bar)
> in
> {
> assert(bar != 0);
> }
> body
> {
> return bar + 1;
> }
>
> The thing I like more about debug statements, is that I can put them
> anywhere in my code, testing parameters and locals in the same way. If
> "for documentation" is the only argument for contracts, I find that a
> bit weak.
>
> int foo(int bar)
> {
> debug assert(bar != 0);
>
> return bar + 1;
> }
>
> That is much cleaner syntax and just as easy to understand from a
> assertion-failure/documentation standpoint IMO.

First of all, you don't really need the debug statements, assertions are 
stripped from -release'd code anyway.

The assertions in the function body are not part of the function 
interface. (eventually, contracts can be on function declarations 
lacking a function body) Conceptually, with an assert in the function 
body, the bug would be inside the function: If it is not assumed in the 
in-contract it cannot be asserted that bar is != 0. Some code could just 
go ahead and call foo(0). If the assertion is in the in-contract, foo(0) 
is invalid. And in the in-contract, this is supposed to be visible for 
everyone.

For a pragmatic reason, because contracts are supposed to be inherited 
(but due to a bug, in-contracts are not currently inherited without 
adding an in{assert(false);} contract to the overriding function, this 
bug does not break LSP though, it is just a little annoying)

Contracts can also be used for modular static model checking/static 
error detection.

You may want to have a look at the Eiffel and Spec# systems.
February 04, 2012
Re: Contracts vs debug
Timon Gehr wrote:
> First of all, you don't really need the debug statements, 
> assertions are stripped from -release'd code anyway.
>
> The assertions in the function body are not part of the 
> function interface. (eventually, contracts can be on function 
> declarations lacking a function body) Conceptually, with an 
> assert in the function body, the bug would be inside the 
> function: If it is not assumed in the in-contract it cannot be 
> asserted that bar is != 0. Some code could just go ahead and 
> call foo(0). If the assertion is in the in-contract, foo(0) is 
> invalid. And in the in-contract, this is supposed to be visible 
> for everyone.
>
> For a pragmatic reason, because contracts are supposed to be 
> inherited (but due to a bug, in-contracts are not currently 
> inherited without adding an in{assert(false);} contract to the 
> overriding function, this bug does not break LSP though, it is 
> just a little annoying)
>
> Contracts can also be used for modular static model 
> checking/static error detection.
>
> You may want to have a look at the Eiffel and Spec# systems.

All that makes sense. I forgot about Inheritance. Thank you for 
the explanation.
February 04, 2012
Re: Contracts vs debug
On Sat, 04 Feb 2012 18:18:22 +0100, F i L <witte2008@gmail.com> wrote:

> Why/where should I use contracts vs debug statements? Is it completely  
> arbitrary? If so, I wonder if contracts syntax is even needed:
>
>     int foo(int bar)
>     in
>     {
>         assert(bar != 0);
>     }
>     body
>     {
>         return bar + 1;
>     }
>
> The thing I like more about debug statements, is that I can put them  
> anywhere in my code, testing parameters and locals in the same way. If  
> "for documentation" is the only argument for contracts, I find that a  
> bit weak.
>
>     int foo(int bar)
>     {
>         debug assert(bar != 0);
>
>         return bar + 1;
>     }
>
> That is much cleaner syntax and just as easy to understand from a  
> assertion-failure/documentation standpoint IMO.

The idea is also that contracts will be inherited. A subclass may
relax the 'in' contracts and strengthen the 'out' contracts. I am
not sure if this currently works, but that is the idea.
Top | Discussion index | About this forum | D home