View mode: basic / threaded / horizontal-split · Log in · Help
June 26, 2005
Design by contract on/off
Hello all.

Maybe I'm not understand design by contract ideology completly, but I'd 
like to be able to compile module ignoring all "assert", "invariant" and 
"out" statements and leaving "in" and "unittest"s. For stable modules 
such compiler flag can speed up module routines by ignoring 
performance-expensive conditions in above statements but in the same 
time guarantee work correctness by controling input arguments in "in" 
statements.

In another words when your module works as expected the only thing that 
can corrupt its stable work is unexpected input arguments from another 
modules that use it. So it would be nice if I can control external 
effect and ignore internal bug traps.

-- 
Victor (aka nail) Nakoryakov
nail-mail<at>mail<dot>ru

Krasnoznamensk, Moscow, Russia
June 26, 2005
Re: Design by contract on/off
Victor Nakoryakov says...
>
>Hello all.
>
>Maybe I'm not understand design by contract ideology completly, but I'd 
>like to be able to compile module ignoring all "assert", "invariant" and 
>"out" statements and leaving "in" and "unittest"s. For stable modules 
>such compiler flag can speed up module routines by ignoring 
>performance-expensive conditions in above statements but in the same 
>time guarantee work correctness by controling input arguments in "in" 
>statements.
>
>In another words when your module works as expected the only thing that 
>can corrupt its stable work is unexpected input arguments from another 
>modules that use it. So it would be nice if I can control external 
>effect and ignore internal bug traps.

You remove all these tests (except the unittests) with the -release flag. You're
not supposed, according to the contract ideology, to put checks for runtime
conditions in the contracts, only the "internal bug traps". In other words, you
will have to put the controls for external effects in the function's body.

Nick
June 26, 2005
Re: Design by contract on/off
Nick wrote:

> You remove all these tests (except the unittests) with the -release flag. You're
> not supposed, according to the contract ideology, to put checks for runtime
> conditions in the contracts, only the "internal bug traps". In other words, you
> will have to put the controls for external effects in the function's body.
> 
> Nick

Oh, I'm totally forgot that unittests are enabled/disabled with separate 
compiler flag, sorry.

I think you didn't understand me completely. Maybe it would be better if 
I explain my idea on example. Consider module

module matrix;

...

void polarDecomposition(in Matrix44 M, out Matrix44 Q, out Matrix44 S)
in
{
	assert(M.isAffine);
}
out
{
	assert(Q.isRotation);
	assert(S.isDiagonal);
}
body
{
	...
	...
	assert(someInternalVal < 10);
	assert(someInternalMat.inverse.transposed == someInternalMat);
	...
	...
}
...

Well if I'm sure that the algorithm is correct I need not to check that 
the result is unexpected and I can skip expensive internal asserts that 
performs matrix inversion on each of N iterations. But I'd like to 
preserve input argument checking, because if it would not satisfy 
algorithm requirements the results will be unpredictable. And then when 
I will release final version of my product I would want to totally 
disable all contract checking.

-- 
Victor (aka nail) Nakoryakov
nail-mail<at>mail<dot>ru

Krasnoznamensk, Moscow, Russia
June 26, 2005
Re: Design by contract on/off
In article <d9m5t2$2ln5$2@digitaldaemon.com>, Victor Nakoryakov says...
>
>Hello all.
>
>Maybe I'm not understand design by contract ideology completly, but I'd 
>like to be able to compile module ignoring all "assert", "invariant" and 
>"out" statements and leaving "in" and "unittest"s. For stable modules 
>such compiler flag can speed up module routines by ignoring 
>performance-expensive conditions in above statements but in the same 
>time guarantee work correctness by controling input arguments in "in" 
>statements.
>
>In another words when your module works as expected the only thing that 
>can corrupt its stable work is unexpected input arguments from another 
>modules that use it. So it would be nice if I can control external 
>effect and ignore internal bug traps.
>
>-- 
>Victor (aka nail) Nakoryakov
>nail-mail<at>mail<dot>ru
>
>Krasnoznamensk, Moscow, Russia

+1 
I'm also missing that (think about the viewpoint of someone who's writing a
library, for example). BTW, I don't think D's distinction between release and
debug builds in this respect has anything to do with the DBC idea in general
(as I understand it).

Just my 2 c,
Stefan
June 27, 2005
Re: Design by contract on/off
>I think you didn't understand me completely. Maybe it would be better if 
>I explain my idea on example. Consider module
>
[snip]
>body
>{
>	...
>	...
>	assert(someInternalVal < 10);
>	assert(someInternalMat.inverse.transposed == someInternalMat);
>	...
>	...
>}
>...
>
>Well if I'm sure that the algorithm is correct I need not to check that 
>the result is unexpected and I can skip expensive internal asserts that 
>performs matrix inversion on each of N iterations. But I'd like to 
>preserve input argument checking, because if it would not satisfy 
>algorithm requirements the results will be unpredictable. And then when 
>I will release final version of my product I would want to totally 
>disable all contract checking.

Ok, I think I understand. What you are saying is that you would like to remove
some asserts, and keep others, right? Is it possible to solve this by using
version or debug statements? What I would do (and have done) in this situation
is

> debug(expensiveChecks)
> {
>   assert(someInternalVal < 10);
>   assert(someInternalMat.inverse.transposed == someInternalMat);
> }

and remove the appropriate -debug switch when it's no longer need. Or in some
cases just use good all fasioned /*comments*/ :)

Nick
June 28, 2005
Re: Design by contract on/off
Nick wrote:
> 
> Ok, I think I understand. What you are saying is that you would like to remove
> some asserts, and keep others, right?

I would like to remove all asserts that are not in

in
{
	...
}

scope.

> Is it possible to solve this by using
> version or debug statements? What I would do (and have done) in this situation
> is

Possible, of course. But separate solution is more elegant.


-- 
Victor (aka nail) Nakoryakov
nail-mail<at>mail<dot>ru

Krasnoznamensk, Moscow, Russia
June 30, 2005
Re: Design by contract on/off
"Victor Nakoryakov" <nail-mail@mail.ru> wrote in message 
news:d9m5t2$2ln5$2@digitaldaemon.com...
> Hello all.
>
> Maybe I'm not understand design by contract ideology completly, but I'd 
> like to be able to compile module ignoring all "assert", "invariant" and 
> "out" statements and leaving "in" and "unittest"s. For stable modules such 
> compiler flag can speed up module routines by ignoring 
> performance-expensive conditions in above statements but in the same time 
> guarantee work correctness by controling input arguments in "in" 
> statements.
>
> In another words when your module works as expected the only thing that 
> can corrupt its stable work is unexpected input arguments from another 
> modules that use it. So it would be nice if I can control external effect 
> and ignore internal bug traps.
>
> -- 
> Victor (aka nail) Nakoryakov
> nail-mail<at>mail<dot>ru
>
> Krasnoznamensk, Moscow, Russia

agreed (though possibly not necessarily about the unittest being included 
with in contracts). Currently 'in' contracts shouldn't be used for input 
validation for any routine destined for a library (IMHO). In particular 
several bugs in std.stream would have been caught ages ago if the 'in' 
contracts had been enforced in the shipping build. When I moved the 'in' 
contracts contents to the body people found their code stopped working.
Top | Discussion index | About this forum | D home