When are blogs deleted from the list of the blogs I've read?
Unit Testing and Test Cases
Hello Guest
  
  • Login
• Register…
• Start blog
  • Who, Where, When
• What is interesting here?
• Duels
  • Polls
• Avatars
• Interests
  • Cities and Countries
• Random blog
• Users search
  • Search
• Games
• Tests
• QAIX
  • Сообщества
• Talxy Chat
• Horoscope
• Online
 
Register!

QAIX > Software, Computer Help > Unit Testing and Test Cases 7 March 2006 20:34:47

  Top users: 
  Recent blog posts: 
  They have birthday today: 
  Forums:   
  Discuss: 
  Recent forum topics: 
  Recent forum comments:
  Модератор:

Unit Testing and Test Cases

Water Cooler v2 27 February 2006 14:44:08
 Here's my understanding as of now.

If I were writing a function

bool IsValidContact(Offe­rer objOfferer, Accepter objAccepter,
TermsAndConditions objTermsAndConditio­ns);


Before writing the function, I'd enlist all the conditions that must be
met for a contract to be valid. Something along the lines of:

1. There must be a valid offer made by an offerer;
2. There must be an unconditional, voluntary acceptance of the offer;
3. The offerer and accepter must be above the age of minority;
4. There must be a valid consideration (quid pro quo).

Though there are many more conditions, for the sake of simplicity, let
us stick to only the above four conditions.

Going from the above four, I'd translate them into code precondition
checks as follows:


1. Assert (objOfferer != null)
2. Assert (objAccepter.Accept­ance.IsVoluntary() &&
objAccepter.Accepta­nce.IsUnconditional(­))
3. Assert ((objOfferer.Age >= ObjLawOfMinority.Mi­nimumAge) &&
((objAccepter.Age >= ObjLawOfMinority.Mi­nimumAge))
4. Assert (objTermsAndConditi­ons.Consideration.Va­lue > 0)


These four would be the basis of unit tests after writing code.

In the implementation, I'd use Design By Contract (DBC) style
assertion:

if (objOfferer == null)
return false;

if (SomeOtherCondition­ Not Met)
return false;



Or I might use the straight-forward-on­e-return-path style design like,


if (objOfferer)
if (SomeOtherCondition­ Met)
return true;



After writing the implementation of the above function, I'd write unit
test scripts to test each of the above conditions. These would be
seperate functions that would call the function IsValidContract with
invalid and valid values against each of the above four conditions we
outlined.

Now, let me in on some terminology. Which of the above are test cases
and what is the unit tests here?

Add comment
Water Cooler v2 27 February 2006 17:47:22 permanent link ]
 
Thanks for your diligent reply, Laurent. It has been very helpful and
interesting.


I think I follow you and believe that my understanding has been correct
so far. What still intrigues me is:

1. What then, are pre-conditions?

My initial assessment showed they were conditions to test inside the
function's implementation, before the function returned valid input. If
they're not that, what are they?


2. I understood the unit-test script you wrote called
testIsValidContract­. You tested it for one condition/validatio­n, and as
it concurs with my understanding, you imply that it must extend for all
such validations. Fine. But what about test-cases. You said, they are a
specification of what input the function gets and what it spits out. My
question precisely is, "what is the format in which they are written?"
Could you please produce a list of test-cases for this example we've
taken? That would give me an outline.


Thanks.

Add comment
Daniel T. 27 February 2006 18:22:36 permanent link ]
 In article <1141051642.754991.­221520@u72g2000cwu.g­ooglegroups.com>,
"Water Cooler v2" <wtr_clr@yahoo.com>­ wrote:
Thanks for your diligent reply, Laurent. It has been very helpful and> interesting.>
I think I follow you and believe that my understanding has been correct> so far. What still intrigues me is:>
1. What then, are pre-conditions?>
My initial assessment showed they were conditions to test inside the> function's implementation, before the function returned valid input. If> they're not that, what are they?

A pre-condition is something about the input such that, if the condition
doesn't hold, the function's result is undefined. In other words, if the
precondition doesn't hold, the function has no way of knowing what to
return. There may be no preconditions in your function.

To put it another way, preconditions are conditions that your function
doesn't have to test, because they must hold *before* the function can
be called.

2. I understood the unit-test script you wrote called> testIsValidContract­. You tested it for one condition/validatio­n, and as> it concurs with my understanding, you imply that it must extend for all> such validations. Fine. But what about test-cases. You said, they are a> specification of what input the function gets and what it spits out. My> question precisely is, "what is the format in which they are written?"> Could you please produce a list of test-cases for this example we've> taken? That would give me an outline.

The format for the unit tests depends on the language and test harness
used, but they are written *outside* the function. A test case should
create some input, call the function with that input, then test the
output to see if it is correct.

The tests can also be used by implementers of code that use your
function as examples of proper use.


--
Magic depends on tradition and belief. It does not welcome observation,
nor does it profit by experiment. On the other hand, science is based
on experience; it is open to correction by observation and experiment.
Add comment
Laurent Bossavit 27 February 2006 18:51:17 permanent link ]
 
My initial assessment showed they were conditions to test inside the> function's implementation, before the function returned valid input.

That's right, as long as you're careful with the implications of that
definition. Preconditions are conditions that must prevail for the
function to have a meaningful result. If preconditions are not met upon
entry, that means someone is using the function wrongly. In other words,
someone wrote a bug, and the bug isn't inside the function.

A major benefit of DbC in my opinion is that it makes it easier, in just
that way, to reason about "where the bug is". A precondition violation
implies a bug in the caller; a postcondition violation imples a bug in
the function called.

Thus,
objOfferer != null
is a precondition. It is incorrect to call the function with a null
offerer.

However,
objTermsAndConditio­ns.Consideration.Val­ue > 0
cannot be a precondition, since you *expect* that the function will
sometimes be called with terms that do not comply with this criterion.
The point of writing the function is that it should tell you when that
is the case, by returning FALSE.
But what about test-cases. You said, they are a> specification of what input the function gets and what it spits out. My> question precisely is, "what is the format in which they are written?"

It depends. :)­

I'm a practitioner of Test-Driven Development. I write down test cases
in the format of unit tests.

So, the testIsValidContract­ function I sketched is both things:
- a test case (it specifies inputs and outputs)
- an executable unit test

You can also write down test cases in some other format. On paper, or on
the whiteboard (I do that on occasion), in Excel tables... The precise
format depends on what it is you're coding.

Laurent
Add comment
Oliver Wong 27 February 2006 20:09:04 permanent link ]
 
"Water Cooler v2" <wtr_clr@yahoo.com>­ wrote in message
news:1141051642.754­991.221520@u72g2000c­wu.googlegroups.com.­..>
1. What then, are pre-conditions?>
My initial assessment showed they were conditions to test inside the> function's implementation, before the function returned valid input. If> they're not that, what are they?

There was an argument about this earlier in the newsgroup, so I'm going
to qualify my answer with "this is my opinion; not everyone agrees with it":

A pre-condition is a condition which must be true for your function to
behave correctly. If the pre-condition is not true, then there is no
guarantee as to how the function will behave.

When you're implementing a function, the pre-conditions are things which
you can assume to be true. When calling a function, the pre-conditions are
things which you must ensure are true in order for the function you're
calling to actually be useful.

Here's an example with trivial (perhaps satirical) pre-conditions:

/*
Pre-conditions:
(*) God will not change the laws of logic.
(*) a gamma ray will not strike the computer, flipping bits randomly.
(*) the compiler will not mess up the translation of the function into
machine code.
*/
public boolean getFalse() {
return false;
}

Here's a somewhat more practical example:

/*
Pre-conditions:
(*) x is not zero
*/
public double getMultiplicativeIn­verse(double x) {
return 1.0 / x;
}

- Oliver

Add comment
Miguel Oliveira e Silva 27 February 2006 22:20:55 permanent link ]
 Water Cooler v2 wrote:
Thanks for your diligent reply, Laurent. It has been very helpful and> interesting.>
I think I follow you and believe that my understanding has been correct> so far. What still intrigues me is:>
1. What then, are pre-conditions?>
My initial assessment showed they were conditions to test inside the> function's implementation, before the function returned valid input. If> they're not that, what are they?

They are the client's part of the routine's contract.

It is up to the client's to ensure a routine precondition
*before* a call is attempted (however, a wise supplier
should protect itself from erroneous preconditions, as
explained below).

In return, the client will be ensured *after* its
execution - if the routine is correct - that
the routine's postconditions will hold.

Another very important assertion in the OO world
are class invariants. Invariants are conditions required
to hold immediately before and immediately after any
use of an object (those periods are named: object
stable times).

Together these three assertions, if used correctly,
allow the programmer to express the (approximate)
semantics of the object's Abstract Data Type.

Ideally all those assertions should be ensured
statically (at compile time), situation in which
the program would be correct (regarding
those assertions).

However, such ideal and desirable goal is not
possible for most practical programs.
One is then faced to what to do when there
is the possibility (hopefully, very remote)
of a run-time assertion failure.

We can identify four possible approaches to this
problematic run-time situation:

1. Ostrich approach: Ignore the problem.

2. Defensive programming approach: convert the
problem to the normal program control flow (if's).

3. "All-or-nothing" approach: decorate the program
with C like "asserts" in the place of runnable assertions,
ensuring that either the program meets all of its
assertions at run-time, or else terminates with
an appropriate error message.

4. DbC approach: make all those assertions part
of the programming language and relate them
with the exception mechanism. A failure of
an assertion raises an exception.

Only the last two approaches are appropriate
to properly handle run-time contracts.

BTW, it makes no practical sense to discuss what
postcondition should a routine "ensure" when a
precondition fails. When a precondition fails we
are in the presence of a program error, of the
responsibility of the caller. The routine should
never be executed in those cases.

Nevertheless, the routine *implementation* should
always assume the the precondition holds (and, after
the routine execution, the caller's code should always
assume the routine's postcondition holds).

Class assertions are not part of the class implementation,
they are part of its interface (and it is there that they should
be tested, whenever it is possible and there is no static
guarantee that they are always verified).

(Being part of the class interface they are required
to be properly inherited by descendant classes: a
very difficult behavior to ensure in C++ or in
standard Java).

When a run-time assertion fails, the (wise) programmer(s)
should only take one of two paths:

1. The program error should be identified and
corrected to ensure its inexistence next time
the program is to be executed ("all-or-nothing",
or DbC approaches);

2. In critical applications, an appropriate safe fault tolerant
technique should be devised and implemented within the
program itself (DbC approach).
(...)>
Thanks.

Best regards,

-miguel

--
Miguel Oliveira e Silva

Add comment
Daniel T. 28 February 2006 03:33:17 permanent link ]
 In article <44035117.A32AC86E@­det.ua.pt>,
Miguel Oliveira e Silva <mos@det.ua.pt> wrote:
Water Cooler v2 wrote:>
Thanks for your diligent reply, Laurent. It has been very helpful and> > interesting.> >
I think I follow you and believe that my understanding has been correct> > so far. What still intrigues me is:> >
1. What then, are pre-conditions?> >
My initial assessment showed they were conditions to test inside the> > function's implementation, before the function returned valid input. If> > they're not that, what are they?>
They are the client's part of the routine's contract.>
It is up to the client's to ensure a routine precondition> *before* a call is attempted (however, a wise supplier> should protect itself from erroneous preconditions, as> explained below).

A nice write up except for this one problem. If the supplier is able to
protect itself from erroneous inputs, then it can define proper outputs
for those inputs, thus making them no longer erroneous.

Someone else's example:

double inverse( double x ) {
return 1/x;
}

The precondition of course is that 'x != 0' however, thats an easy thing
to check, and as such one can define a particular output for that
condition:

// returns NaN if x == 0
double inverse( double x ) {
return 1/x;
}

On the other hand, some functions have preconditions that can't be
checked. For example C++'s std::copy takes two input iterators that must
be in a range (ie incrementing the first iterator must eventually make
it equal to the second.) This cannot be checked from inside the routine,
even theoretically. Now that's a *real* precondition.
In return, the client will be ensured *after* its> execution - if the routine is correct - that> the routine's postconditions will hold.>
Another very important assertion in the OO world> are class invariants. Invariants are conditions required> to hold immediately before and immediately after any> use of an object (those periods are named: object> stable times).>
Together these three assertions, if used correctly,> allow the programmer to express the (approximate)> semantics of the object's Abstract Data Type.>
Ideally all those assertions should be ensured> statically (at compile time), situation in which> the program would be correct (regarding> those assertions).>
However, such ideal and desirable goal is not> possible for most practical programs.> One is then faced to what to do when there> is the possibility (hopefully, very remote)> of a run-time assertion failure.>
We can identify four possible approaches to this> problematic run-time situation:>
1. Ostrich approach: Ignore the problem.>
2. Defensive programming approach: convert the> problem to the normal program control flow (if's).>
3. "All-or-nothing" approach: decorate the program> with C like "asserts" in the place of runnable assertions,> ensuring that either the program meets all of its> assertions at run-time, or else terminates with> an appropriate error message.>
4. DbC approach: make all those assertions part> of the programming language and relate them> with the exception mechanism. A failure of> an assertion raises an exception.>
Only the last two approaches are appropriate> to properly handle run-time contracts.

For real preconditions, none of the above approaches will work. You
can't ignore the problem, and you can't write code to protect yourself
from it.


--
Magic depends on tradition and belief. It does not welcome observation,
nor does it profit by experiment. On the other hand, science is based
on experience; it is open to correction by observation and experiment.
Add comment
Miguel Oliveira e Silva 28 February 2006 19:38:41 permanent link ]
 "Daniel T." wrote:
In article <44035117.A32AC86E@­det.ua.pt>,> Miguel Oliveira e Silva <mos@det.ua.pt> wrote:>
Water Cooler v2 wrote:> >
Thanks for your diligent reply, Laurent. It has been very helpful and> > > interesting.> > >
I think I follow you and believe that my understanding has been correct> > > so far. What still intrigues me is:> > >
1. What then, are pre-conditions?> > >
My initial assessment showed they were conditions to test inside the> > > function's implementation, before the function returned valid input. If> > > they're not that, what are they?> >
They are the client's part of the routine's contract.> >
It is up to the client's to ensure a routine precondition> > *before* a call is attempted (however, a wise supplier> > should protect itself from erroneous preconditions, as> > explained below).>
A nice write up except for this one problem. If the supplier is able to> protect itself from erroneous inputs, then it can define proper outputs> for those inputs, thus making them no longer erroneous.

That is not correct.

Most electronic circuits - for example the components used
to build computers - protected themselves against incorrect
connections (through appropriate interface physical shapes)
and even against out of bound voltage signals (through
appropriate protecting circuits). That protection is *not part*
of the normal component behavior, neither is part of the
component's contract to the outside world: it is simply
a way for the component to protect itself against *incorrect*
uses (thus increasing its fault tolerance and life span).
Nothing - other than malfunction - is expected from an
electronic circuit when it is incorrectly used (thus one
cannot "define proper outputs for those inputs" as you
said). Nevertheless, a wise electronic engineer (eager
to keep its job) protects, as much as reasonable, its
circuits against incorrect external uses.

Same thing with assertions.

It seems to me, that you are incorrectly mixing the world
of normal program behavior, and the world of exceptions
and exceptional behavior. Contracts aim at correctness
in the normal program behavior. Exceptions exist as a
mean to deal with (detectable) incorrect programs
(in DbC it is as simply as this).
Someone else's example:>
double inverse( double x ) {> return 1/x;> }>
The precondition of course is that 'x != 0'

It should be part of the function interface as in Eiffel:

inverse(x: DOUBLE): DOUBLE is
require -- precondition
x /= 0
do
Result := 1/x
ensure -- postcondition
(Result * x - 1).abs <= Maximum_acceptable_­near_zero_value
end;
however, thats an easy thing> to check,

Indeed it is.
and as such one can define a particular output for that> condition:>
// returns NaN if x == 0> double inverse( double x ) {> return 1/x;> }

You surely can, but you surely shouldn't (or else
you will be doing defensive programming and not
DbC).

That said, of course the programmer is free to
establish the contracts we wants to its classes
and routines.

Of course, in this particular (mathematical) case
it would not be wise to remove the precondition
(and extend the postcondition with a NaN result
value when x equals zero).

I don't see the interest of dividing anything by zero.
There are some very important mathematical and
engineering uses for "extracting" square roots out
of negative values, but none to my knowledge out
of x/0.

99.99...99% of 1/0 uses are programming errors
(and should be treated as such).
On the other hand, some functions have preconditions that can't be> checked.

Yes, that situation can occur (the world is not perfect).
Manytimes times we can only make a practical
runnable approximation of the required precondition.

Why do you think that, somehow, this practical limitation
contradicts anything that I have written (the "all-or-nothing"
and the DbC's exceptional behavior was clearly identified as
applying to *runnable* assertions)?

Are you, by any chance, defending that a program should
not have runnable preconditions?

If you are, then that is not DbC: it is defensive programming.
For example C++'s std::copy takes two input iterators that must> be in a range (ie incrementing the first iterator must eventually make> it equal to the second.) This cannot be checked from inside the routine,> even theoretically.

So?

Are you saying that we should not use iterators unwisely
or in critical code? If you are, I agree (at least the C++'s
iterators you refer).

Of course there can exist situations in which
we cannot express runnable assertions. However,
as in the example you give, many times the
programmer is free to choose the library that
better fills its needs (why should he use a blind
copy of unsafe iterators?).
Now that's a *real* precondition.

What do you mean by "real"?

(Surely you are not stating that runnable
preconditions are not real!)

A better name would be hard or difficult.
In return, the client will be ensured *after* its> > execution - if the routine is correct - that> > the routine's postconditions will hold.> >
Another very important assertion in the OO world> > are class invariants. Invariants are conditions required> > to hold immediately before and immediately after any> > use of an object (those periods are named: object> > stable times).> >
Together these three assertions, if used correctly,> > allow the programmer to express the (approximate)> > semantics of the object's Abstract Data Type.> >
Ideally all those assertions should be ensured> > statically (at compile time), situation in which> > the program would be correct (regarding> > those assertions).> >
However, such ideal and desirable goal is not> > possible for most practical programs.> > One is then faced to what to do when there> > is the possibility (hopefully, very remote)> > of a run-time assertion failure.> >
We can identify four possible approaches to this> > problematic run-time situation:> >
1. Ostrich approach: Ignore the problem.> >
2. Defensive programming approach: convert the> > problem to the normal program control flow (if's).> >
3. "All-or-nothing" approach: decorate the program> > with C like "asserts" in the place of runnable assertions,> > ensuring that either the program meets all of its> > assertions at run-time, or else terminates with> > an appropriate error message.> >
4. DbC approach: make all those assertions part> > of the programming language and relate them> > with the exception mechanism. A failure of> > an assertion raises an exception.> >
Only the last two approaches are appropriate> > to properly handle run-time contracts.>
For real preconditions, none of the above approaches will work.

("Real"?)

There are three kinds of assertions:

1. Those that can be ensured statically (the ideal goal);

2. Those that can be checked at run-time (the practical
compromise);

3. All the remaining (the "comment" ones).

A wise programmer attempts to put assertions, as much as
is possible (and reasonable), in the group 1; then he attempts
to put the remaining in the group 2 (even if only some
practical approximations); only then, he should use
comments to informally express the remaining ones
(this last group of assertions will only serve as a
documentation aid).
You can't ignore the problem, and you can't write code to protect yourself> from it.

Perhaps not completely (sometimes), but some protection is surely
possible. Even if only *after* the problem as manifest itself.
(The world of runnable assertions is not bound only to preconditions.)

Of course it will be much harder to establish clear responsibilities
between the caller and the callee and to bring objects to stable
usable states (verifying its invariants) if the (precondition) error
is found after the routine starts its internal execution.

All the problems you identify do exist in the practical use
of DbC, but I fail to understand in what way such problems
contradicts anything that I have stated about DbC.
--> Magic depends on tradition and belief. It does not welcome observation,> nor does it profit by experiment. On the other hand, science is based> on experience; it is open to correction by observation and experiment.

Best regards,

-miguel

--
Miguel Oliveira e Silva

Add comment
Martin Brown 28 February 2006 21:34:07 permanent link ]
 Daniel T. wrote:
In article <44035117.A32AC86E@­det.ua.pt>,> Miguel Oliveira e Silva <mos@det.ua.pt> wrote:>
Water Cooler v2 wrote:>>
Thanks for your diligent reply, Laurent. It has been very helpful and>>>interesting.>­>>
I think I follow you and believe that my understanding has been correct>>>so far. What still intrigues me is:>>>
1. What then, are pre-conditions?>>>
My initial assessment showed they were conditions to test inside the>>>function's implementation, before the function returned valid input. If>>>they're not that, what are they?>>
They are the client's part of the routine's contract.>>
It is up to the client's to ensure a routine precondition>>*befo­re* a call is attempted (however, a wise supplier>>should protect itself from erroneous preconditions, as>>explained below).>
A nice write up except for this one problem. If the supplier is able to > protect itself from erroneous inputs, then it can define proper outputs > for those inputs, thus making them no longer erroneous.>
Someone else's example:>
double inverse( double x ) {> return 1/x;> }>
The precondition of course is that 'x != 0' however, thats an easy thing > to check, and as such one can define a particular output for that > condition:>
// returns NaN if x == 0> double inverse( double x ) {> return 1/x;> }

Although you could specify it to return a silent NaN that merely delays
detecting a hard error and contaminates other possibly meaningful future
calculations that use this NaN result.

Generating a trap in most cases would be preferable since it usually
signifies a serious programming error when division by zero occurs.

Your improved definition potentially breaks some code that might be
expected to work algebraically since you can no longer satisfy the
invariant property for the function inverse for all valid inputs.

x == inverse( inverse(x) )

whereas 0 != inverse( inverse(0)) under your definition.

And at present inverse(Nan) is also undefined.

Returning a suitably signed infinity might just be defensible under some
circumstances if the calculation must proceed and cannot be aborted.

Regards,
Martin Brown
Add comment
Daniel T. 28 February 2006 21:57:15 permanent link ]
 In article <du2530$jog$1@newsg­4.svr.pol.co.uk>,
Martin Brown <|||newspam|||@nezu­mi.demon.co.uk> wrote:
Daniel T. wrote:>
In article <44035117.A32AC86E@­det.ua.pt>,> > Miguel Oliveira e Silva <mos@det.ua.pt> wrote:> >
Water Cooler v2 wrote:> >>
Thanks for your diligent reply, Laurent. It has been very helpful and> >>>interesting.> >>>
I think I follow you and believe that my understanding has been correct> >>>so far. What still intrigues me is:> >>>
1. What then, are pre-conditions?> >>>
My initial assessment showed they were conditions to test inside the> >>>function's implementation, before the function returned valid input. If> >>>they're not that, what are they?> >>
They are the client's part of the routine's contract.> >>
It is up to the client's to ensure a routine precondition> >>*before* a call is attempted (however, a wise supplier> >>should protect itself from erroneous preconditions, as> >>explained below).> >
A nice write up except for this one problem. If the supplier is able to > > protect itself from erroneous inputs, then it can define proper outputs > > for those inputs, thus making them no longer erroneous.> >
Someone else's example:> >
double inverse( double x ) {> > return 1/x;> > }> >
The precondition of course is that 'x != 0' however, thats an easy thing > > to check, and as such one can define a particular output for that > > condition:> >
// returns NaN if x == 0> > double inverse( double x ) {> > return 1/x;> > }>
Although you could specify it to return a silent NaN that merely delays > detecting a hard error and contaminates other possibly meaningful future > calculations that use this NaN result.>
Generating a trap in most cases would be preferable since it usually > signifies a serious programming error when division by zero occurs.

I have no problem with that, it's still a defined result.
Your improved definition potentially breaks some code that might be > expected to work algebraically since you can no longer satisfy the > invariant property for the function inverse for all valid inputs.>
x == inverse( inverse(x) )>
whereas 0 != inverse( inverse(0)) under your definition.>
And at present inverse(Nan) is also undefined.

We'd have to define that as well I guess. "ensure inverse(NaN) == 0"


--
Magic depends on tradition and belief. It does not welcome observation,
nor does it profit by experiment. On the other hand, science is based
on experience; it is open to correction by observation and experiment.
Add comment
Dmitry A. Kazakov 28 February 2006 22:00:23 permanent link ]
 On Tue, 28 Feb 2006 16:38:41 +0000, Miguel Oliveira e Silva wrote:
"Daniel T." wrote:
It seems to me, that you are incorrectly mixing the world> of normal program behavior, and the world of exceptions> and exceptional behavior.

A behavior is either correct or not. A program exposing incorrect behavior
is incorrect. [That correctness might be undecidable changes here nothing.]
Exceptions exist as a> mean to deal with (detectable) incorrect programs> (in DbC it is as simply as this).

Exceptions are used for control flow in correct programs. Exceptions in
incorrect programs are presumably incorrect.
and as such one can define a particular output for that>> condition:>>
// returns NaN if x == 0>> double inverse( double x ) {>> return 1/x;>> }>
You surely can, but you surely shouldn't (or else> you will be doing defensive programming and not> DbC).

Extended numeric sets are proven to be mathematically correct and deliver
far safer and efficient computations than ones defined on bound numeric
subsets. NaN is a *legal* value of IEEE float. It is a valid outcome of
division a finite number by exact zero. Better could be only full-scaled
interval arithmetic with infinity ideals.
Now that's a *real* precondition.>
What do you mean by "real"?

= used to determine correctness of the program.
(Surely you are not stating that runnable> preconditions are not real!)

That is the only possibility, as I have shown in our previous discussion. I
think there is no need to repeat it.

--
Regards,
Dmitry A. Kazakov
http://www.dmitry-k­azakov.de
Add comment
Miguel Oliveira e Silva 28 February 2006 22:59:19 permanent link ]
 "Dmitry A. Kazakov" wrote:
On Tue, 28 Feb 2006 16:38:41 +0000, Miguel Oliveira e Silva wrote:>
"Daniel T." wrote:>
It seems to me, that you are incorrectly mixing the world> > of normal program behavior, and the world of exceptions> > and exceptional behavior.>
A behavior is either correct or not. A program exposing incorrect behavior> is incorrect. [That correctness might be undecidable changes here nothing.]

Agreed.
Exceptions exist as a> > mean to deal with (detectable) incorrect programs> > (in DbC it is as simply as this).>
Exceptions are used for control flow in correct programs.

Not in DbC. That would be an unacceptable abuse of exceptions.

A correct program should never raise exceptions.

In DbC, exceptions are used to deal with incorrect programs
(broken contracts).
Exceptions in incorrect programs are presumably incorrect.

Nope. They *correctly* signal an *incorrect* program
(as in physical sciences when an experience whose results
contradicts what was expected from a theoretical law,
proves *correctly* that the law is *incorrect*).
and as such one can define a particular output for that> >> condition:> >>
// returns NaN if x == 0> >> double inverse( double x ) {> >> return 1/x;> >> }> >
You surely can, but you surely shouldn't (or else> > you will be doing defensive programming and not> > DbC).>
Extended numeric sets are proven to be mathematically correct and deliver> far safer and efficient computations than ones defined on bound numeric> subsets. NaN is a *legal* value of IEEE float.

(So what?)

I fail to see suitable uses of a NaN number ("Not-a-Number" number)
other than to express an error within the number representation,
but - by all means - be free to use that defensive approach to
inverse [inverse(0) = NaN].

Just don't forget that the inverse function (as all functions) are
is not an end in it selves, but a mean to reach somewhere.
I'll bet that in 99.99...99% if the times the client of inverse
is not expecting to divide by zero, neither such result makes
any sense to whatever calculation required the use of this
function.

The class/routine implementor is free to set up whatever
contract he wants. However, once defined, their clients are
bound to observe them. So if the inverse function defines
(as it should) the precondition of a non-zero argument,
then we are in the presence of an incorrect program
when x equals zero (regardless of the routine's
postcondition).
It is a valid outcome of> division a finite number by exact zero. Better could be only full-scaled
interval arithmetic with infinity ideals.>
Now that's a *real* precondition.> >
What do you mean by "real"?>
= used to determine correctness of the program.

What?

Are you saying that the non-zero x precondition
of inverse is not useful to determine the correctness
of a program?
(Surely you are not stating that runnable> > preconditions are not real!)>
That is the only possibility, as I have shown in our previous discussion.

(I missed that demonstration.)

If that is your opinion, then don't call it DbC, or else you
will be confusing everyone who does not know what is
this methodology.
I think there is no need to repeat it.

No it is not. It is only necessary a little effort to understand
what I'm saying, and what DbC is.
[B. Meyer, Object-Oriented Software Construction, 2ed,
pages 331-438]
--> Regards,> Dmitry A. Kazakov> http://www.dmitry-k­azakov.de

Best regards,

-miguel

--
Miguel Oliveira e Silva

Add comment
Oliver Wong 28 February 2006 23:47:02 permanent link ]
 
"Miguel Oliveira e Silva" <mos@det.ua.pt> wrote in message
news:4404AB97.37B38­F68@det.ua.pt...> "Dmitry A. Kazakov" wrote:>
On Tue, 28 Feb 2006 16:38:41 +0000, Miguel Oliveira e Silva wrote:>>
"Daniel T." wrote:>>
Exceptions are used for control flow in correct programs.>
Not in DbC. That would be an unacceptable abuse of exceptions.>
A correct program should never raise exceptions.

What if the contract specifically states that the behaviour of a given
method is to raise an exception? E.g.

/*
Pre-conditions: None.
Post-conditions: NullPointerExceptio­n must be raised.
*/
void raiseNPE() {
/*Implementation goes here*/
}
In DbC, exceptions are used to deal with incorrect programs> (broken contracts).>
Exceptions in incorrect programs are presumably incorrect.>
Nope. They *correctly* signal an *incorrect* program> (as in physical sciences when an experience whose results> contradicts what was expected from a theoretical law,> proves *correctly* that the law is *incorrect*).

Not nescessarily, as shown above (i.e. the exception might correctly be
part of the behaviour of a correctly implemented program). However, if a
program is incorrectly implemented, then perhaps the exception raising
routines are also incorrectly implemented, so raising the exception might
not be a correct signal for anything!

Another example:

/*
Pre-condition: none.
Post-condition: "Hello World!" is printed to the standard out, no exception
will be raised.
*/
void printHelloWorld() {
print "Hello World!"
throw new DivideByZeroExcepti­on();
}

This program is incorrectly implemented, and coincidentally an exception
is raised. But the exception being raised is *INCORRECTLY* signalling the
the incorrectness of the program; it claims that the problem had something
to do with a division by zero, when that was not the nature of the
incorrectness at all. Actually, the incorrectness was simply the presence of
the exception itself!

- Oliver

Add comment
Daniel T. 28 February 2006 23:48:10 permanent link ]
 In article <4404AB97.37B38F68@­det.ua.pt>,
Miguel Oliveira e Silva <mos@det.ua.pt> wrote:
No it is not. It is only necessary a little effort to understand> what I'm saying, and what DbC is.> [B. Meyer, Object-Oriented Software Construction, 2ed,> pages 331-438]

I understand DbC, but DbC is not what I've been discussing here.
Preconditions existed long before Mr. Meyer. Maybe it would avoid
confusion if you used 'require' instead.

As in, "a require clause will cause an exception if its condition is
false." This is very different from what happens if a precondition is
not met.

pre?con?di?tion: n : A condition that must exist or be established
before something can occur or be considered; a prerequisite.

If a precondition is not met, the behavior of the code cannot even be
considered...

With DbC we can wonder what would happen if I sent 0 to the inverse
function, because there is a defined result (an exception will be
generated.) Here, I've been talking about real preconditions, ones that
require being met or we cannot determine the outcome.
Add comment
Daniel T. 1 March 2006 00:24:23 permanent link ]
 In article <aF2Nf.7647$Cp4.716­9@edtnps90>,
"Oliver Wong" <owong@castortech.c­om> wrote:
"Miguel Oliveira e Silva" <mos@det.ua.pt> wrote in message > news:4404AB97.37B38­F68@det.ua.pt...> > "Dmitry A. Kazakov" wrote:> >
On Tue, 28 Feb 2006 16:38:41 +0000, Miguel Oliveira e Silva wrote:> >>
"Daniel T." wrote:> >>
Exceptions are used for control flow in correct programs.> >
Not in DbC. That would be an unacceptable abuse of exceptions.> >
A correct program should never raise exceptions.>
What if the contract specifically states that the behaviour of a given > method is to raise an exception?

Good catch! Exceptions are defined behaviors that correct programs use
to signal problems. Incorrect programs can do literally anything.

In DbC, exceptions are used to deal with incorrect programs> > (broken contracts).> >
Exceptions in incorrect programs are presumably incorrect.> >
Nope. They *correctly* signal an *incorrect* program> > (as in physical sciences when an experience whose results> > contradicts what was expected from a theoretical law,> > proves *correctly* that the law is *incorrect*).>
Not nescessarily, as shown above (i.e. the exception might correctly be > part of the behaviour of a correctly implemented program). However, if a > program is incorrectly implemented, then perhaps the exception raising > routines are also incorrectly implemented, so raising the exception might > not be a correct signal for anything!

Not in DbC, and that is where the confusion lies. Miguel is talking
about DbC and Eiffel's require clause, Dmitry and I are talking about
preconditions.
Another example:>
/*> Pre-condition: none.> Post-condition: "Hello World!" is printed to the standard out, no exception > will be raised.> */> void printHelloWorld() {> print "Hello World!"> throw new DivideByZeroExcepti­on();> }>
This program is incorrectly implemented, and coincidentally an exception > is raised. But the exception being raised is *INCORRECTLY* signalling the > the incorrectness of the program; it claims that the problem had something > to do with a division by zero, when that was not the nature of the > incorrectness at all. Actually, the incorrectness was simply the presence of > the exception itself!

Yes! And why on earth should we be passing control back to the client
(by raising an exception) when we already know that it contains
incorrect code, we know that because it gave us data that didn't meet
our pre-condition?


--
Magic depends on tradition and belief. It does not welcome observation,
nor does it profit by experiment. On the other hand, science is based
on experience; it is open to correction by observation and experiment.
Add comment
Dmitry A. Kazakov 1 March 2006 00:48:31 permanent link ]
 On Tue, 28 Feb 2006 19:59:19 +0000, Miguel Oliveira e Silva wrote:
"Dmitry A. Kazakov" wrote:>
On Tue, 28 Feb 2006 16:38:41 +0000, Miguel Oliveira e Silva wrote:>>
Exceptions exist as a>>> mean to deal with (detectable) incorrect programs>>> (in DbC it is as simply as this).>>
Exceptions are used for control flow in correct programs.>
Not in DbC. That would be an unacceptable abuse of exceptions.>
A correct program should never raise exceptions.

???
Exceptions in incorrect programs are presumably incorrect.>
Nope. They *correctly* signal an *incorrect* program> (as in physical sciences when an experience whose results> contradicts what was expected from a theoretical law,> proves *correctly* that the law is *incorrect*).

Whom they signal to? To the incorrect program? What could an *incorrect*
program *correctly* do about anything? Why would you trust to what an
incorrect program says?

Program: "I am a liar."

Is it?
Extended numeric sets are proven to be mathematically correct and deliver>> far safer and efficient computations than ones defined on bound numeric>> subsets. NaN is a *legal* value of IEEE float.>
(So what?)>
I fail to see suitable uses of a NaN number ("Not-a-Number" number)> other than to express an error within the number representation,

It is the same misunderstanding as above. NaN is not an error, it is not a
number. It is like i=sqrt(-1), which is also not a [real] number, but an
ideal from another set [of complex numbers.]
but - by all means - be free to use that defensive approach to> inverse [inverse(0) = NaN].

IEEE floats don't form a ring. So the theorem above does not hold. So what?
Just don't forget that the inverse function (as all functions) are> is not an end in it selves, but a mean to reach somewhere.> I'll bet that in 99.99...99% if the times the client of inverse> is not expecting to divide by zero, neither such result makes> any sense to whatever calculation required the use of this> function.

That does not influence program correctness. A nice thing about ideals,
like NaN, is that they don't leak. If an algorithm is correct in R without
ideals it stays in R with ideals. So it is 100% safe. You can continue with
NaN to the point where R is needed. Note, not as a precondition, but as a
type conversion. This conversion will raise an exception for NaN. That
would be a correct behavior.
Now that's a *real* precondition.>>>
What do you mean by "real"?>>
= used to determine correctness of the program.>
What?>
Are you saying that the non-zero x precondition> of inverse is not useful to determine the correctness> of a program?

No. I claim that only one of the following two statements is true for a
given program:

1. A predicate is a "real" precondition <=> determines correctness => its
value is not used (handled) by the program

2. A predicate is not a precondition => its value can be handled.
(Surely you are not stating that runnable>>> preconditions are not real!)>>
That is the only possibility, as I have shown in our previous discussion.>
(I missed that demonstration.)

pre: true
function Liar return Boolean is
begin
return not Correct (Liar);
end Liar;
post : Liar

If things determining the program correctness were allowed for evaluation
in the program, that would allow construction of the liar paradox.

So if a precondition determines correctness, then it cannot be checked (=it
is "real"). If it is checked [and the system is not self-contradictory],
then it does not determine the correctness => it is not a precondition.
If that is your opinion, then don't call it DbC, or else you> will be confusing everyone who does not know what is> this methodology.

So in your opinion the "real" DbC is self-contradictory?­ Cool!

--
Regards,
Dmitry A. Kazakov
http://www.dmitry-k­azakov.de
Add comment
Miguel Oliveira e Silva 1 March 2006 01:46:17 permanent link ]
 Oliver Wong wrote:
"Miguel Oliveira e Silva" <mos@det.ua.pt> wrote in message> news:4404AB97.37B38­F68@det.ua.pt...> > "Dmitry A. Kazakov" wrote:> >
On Tue, 28 Feb 2006 16:38:41 +0000, Miguel Oliveira e Silva wrote:> >>
"Daniel T." wrote:> >>
Exceptions are used for control flow in correct programs.> >
Not in DbC. That would be an unacceptable abuse of exceptions.> >
A correct program should never raise exceptions.>
What if the contract specifically states that the behaviour of a given> method is to raise an exception?

I understand what you Daniel and Dmitry are trying to
argue in this point. But as I several times attempted to call
up to your attention, DbC(tm) has a much simpler view of
contracts, normal program behavior and exceptions.
In DbC exceptions are simply the response of a program
to an incorrect behavior due to a broken contract.

There is no need to put exceptions in contracts, because
in DbC when a runnable assertions is false an exception
is required to be raised.

You may argue that exceptions can be used in normal
program control flow (in Eiffel its much harder to do that,
because, unlike Ada/C++/Java its exception mechanism
is tightly bound to DbC). However, I must insist that
such use is inappropriate (even in those languages).
Not only normal conditional instructions are much
more safe, expressive and efficient, but also it mixes
up two different programming worlds: the one bound
to the expected normal behavior of programs, and the
one used to get along with exceptional incorrect behavior.

Also using exceptions for normal program control,
is little more than the disguise use of the unstructured
goto instruction (no more single point of entry and
single point of exit for program components).

The structured property of programs is extremely
important because it is one that allows Hoare/Floyd
formal view of attaching meaning to programs through
preconditions and postconditions (which was one of the
most important earlier work in which Meyer based
his DbC methodology).
E.g.>
/*> Pre-conditions: None.> Post-conditions: NullPointerExceptio­n must be raised.> */> void raiseNPE() {> /*Implementation goes here*/> }>
In DbC, exceptions are used to deal with incorrect programs> > (broken contracts).> >
Exceptions in incorrect programs are presumably incorrect.> >
Nope. They *correctly* signal an *incorrect* program> > (as in physical sciences when an experience whose results> > contradicts what was expected from a theoretical law,> > proves *correctly* that the law is *incorrect*).>
Not nescessarily, as shown above (i.e. the exception might correctly be> part of the behaviour of a correctly implemented program).

I was referring to DbC(tm) in which, as I have mentioned several
times, things are much simpler and responsibilities are much clear.
However, if a> program is incorrectly implemented, then perhaps the exception raising> routines are also incorrectly implemented, so raising the exception might> not be a correct signal for anything!

If the exception is raised as a result of a false assertion, then
it correctly signals a broken contract, even if that contract
is not the intended one.
Another example:>
/*> Pre-condition: none.> Post-condition: "Hello World!" is printed to the standard out, no exception> will be raised.> */> void printHelloWorld() {> print "Hello World!"> throw new DivideByZeroExcepti­on();> }>
This program is incorrectly implemented, and coincidentally an exception> is raised. But the exception being raised is *INCORRECTLY* signalling the> the incorrectness of the program;

Of course the use of the "throw" instruction in programs can
incorrectly raise exceptions (there is no such instruction in Eiffel).
If you take a closer look to my message you'll see that I was
referring to exceptions raised as a result of false assertions
(situation in which they are always correctly raised, even
if the assertion was not intended).
it claims that the problem had something> to do with a division by zero, when that was not the nature of the> incorrectness at all.

Indeed.
Actually, the incorrectness was simply the presence of> the exception itself!

Just because it was not bound to assertions (and DbC).
- Oliver

Best regards,

-miguel

--
Miguel Oliveira e Silva

Add comment
Miguel Oliveira e Silva 1 March 2006 02:09:10 permanent link ]
 "Daniel T." wrote:
In article <aF2Nf.7647$Cp4.716­9@edtnps90>,> "Oliver Wong" <owong@castortech.c­om> wrote:>
"Miguel Oliveira e Silva" <mos@det.ua.pt> wrote in message> > news:4404AB97.37B38­F68@det.ua.pt...> > > "Dmitry A. Kazakov" wrote:> > >
On Tue, 28 Feb 2006 16:38:41 +0000, Miguel Oliveira e Silva wrote:> > >>
"Daniel T." wrote:> > >>
Exceptions are used for control flow in correct programs.> > >
Not in DbC. That would be an unacceptable abuse of exceptions.> > >
A correct program should never raise exceptions.> >
What if the contract specifically states that the behaviour of a given> > method is to raise an exception?>
Good catch! Exceptions are defined behaviors that correct programs use> to signal problems. Incorrect programs can do literally anything.>
In DbC, exceptions are used to deal with incorrect programs> > > (broken contracts).> > >
Exceptions in incorrect programs are presumably incorrect.> > >
Nope. They *correctly* signal an *incorrect* program> > > (as in physical sciences when an experience whose results> > > contradicts what was expected from a theoretical law,> > > proves *correctly* that the law is *incorrect*).> >
Not nescessarily, as shown above (i.e. the exception might correctly be> > part of the behaviour of a correctly implemented program). However, if a> > program is incorrectly implemented, then perhaps the exception raising> > routines are also incorrectly implemented, so raising the exception might> > not be a correct signal for anything!
Not in DbC, and that is where the confusion lies.

All my messages clearly state that I'm writing about DbC(tm).

In fact, the first message I sent (In a thread named: "Design by
contract and unit tests") was a response to an incorrect behavior
attributed explicitly to DbC.
Miguel is talking about DbC and Eiffel's require clause,

I'm not referring specifically to Eiffel's require clause.

DbC can (and should) be used in languages other
than Eiffel (I use it in all the languages I use and teach).
Of course it is be much more difficult to properly
use DbC in languages such as Ada/C++/Java.
For example, in Eiffel class assertions (invariants,
preconditions and postconditions) are part of the
class interface (not its implementation).
Dmitry and I are talking about preconditions.

So am I, and how they relate to class contracts.
Of course I'm not only referring to Hoare/Floyd's
mathematical concept but to the practical DbC
preconditions.

If you take a closer look to my messages you'll see
we don't disagree that much regarding the theoretical
mathematical concept.
(...)

Best regards,

-miguel

--
Miguel Oliveira e Silva

Add comment
Miguel Oliveira e Silva 1 March 2006 02:47:16 permanent link ]
 "Daniel T." wrote:
In article <4404AB97.37B38F68@­det.ua.pt>,> Miguel Oliveira e Silva <mos@det.ua.pt> wrote:>
No it is not. It is only necessary a little effort to understand> > what I'm saying, and what DbC is.> > [B. Meyer, Object-Oriented Software Construction, 2ed,> > pages 331-438]>
I understand DbC, but DbC is not what I've been discussing here.

Ok. But "Water Cooler v2"'s initial message was clearly referring
to DbC.
Preconditions existed long before Mr. Meyer.
Maybe it would avoid confusion if you used 'require' instead.

DbC is a very useful tool in any language (not just Eiffel).
As in, "a require clause will cause an exception if its condition is> false." This is very different from what happens if a precondition is> not met.

What do you propose that should happen in such situations?

In my opinion either:

1. The error is detected statically and program is simply not allowed
to run (the ideal solution);

2. The errors cannot be detected statically, but there is the possibility
to trace them at runtime through runnable assertions. Regardless of this
dynamic typed alike approach, the program is incorrect and it should
behave appropriately (terminate immediately or raise an exception
to allow a fault tolerant alternative path);

3. The error cannot be detected neither statically nor within runnable
assertions. In this case since I'm an atheist there are not much things
I could do... Nevertheless, sooner or later (hopefully, sooner) a
runnable assertion will most likely fail (although not where it should).

Do you have alternative proposals?
pre?con?di?tion: n : A condition that must exist or be established> before something can occur or be considered; a prerequisite.

Exactly.
If a precondition is not met, the behavior of the code cannot even be> considered...

Agreed. The program is incorrect (the error is somewhere within
the caller's code).

However the less the program is allowed to normally
proceed after the error detection, the better (the error
localization is much more precise, and devising fault
tolerant algorithms are much easier and safe).
With DbC we can wonder what would happen if I sent 0 to the inverse> function, because there is a defined result (an exception will be> generated.)

In DbC that's an exceptional behavior (due to a
programming error), not a normal behavior.
Here, I've been talking about real preconditions, ones that> require being met or we cannot determine the outcome.

All preconditions (postconditions, invariants and other assertions)
are required to be met in correct programs. So I think I've been
talking about the same things.

DbC prescribes a very simple and precise behavior.
If you have alternative practical proposals -based on
the mathematical foundations in which most likely
we all agree- I'm all ears.

-miguel

--
Miguel Oliveira e Silva

Add comment
Miguel Oliveira e Silva 1 March 2006 03:40:11 permanent link ]
 "Dmitry A. Kazakov" wrote:
On Tue, 28 Feb 2006 19:59:19 +0000, Miguel Oliveira e Silva wrote:>
"Dmitry A. Kazakov" wrote:> >
On Tue, 28 Feb 2006 16:38:41 +0000, Miguel Oliveira e Silva wrote:> >>
Exceptions exist as a> >>> mean to deal with (detectable) incorrect programs> >>> (in DbC it is as simply as this).> >>
Exceptions are used for control flow in correct programs.> >
Not in DbC. That would be an unacceptable abuse of exceptions.> >
A correct program should never raise exceptions.>
???>
Exceptions in incorrect programs are presumably incorrect.> >
Nope. They *correctly* signal an *incorrect* program> > (as in physical sciences when an experience whose results> > contradicts what was expected from a theoretical law,> > proves *correctly* that the law is *incorrect*).>
Whom they signal to?

In the case of a false precondition, to the routine's client.
To the incorrect program?

Exactly.
What could an *incorrect*> program *correctly* do about anything?

Terminate execution (identifying the error);
or propagate the exception upwards in the
call stack until a point in which it would be
safe to retry an alternative (hopefully, correct)
algorithm (fault tolerance).
Why would you trust to what an> incorrect program says?

It is precisely because we can't trust an
incorrect program, that an exception should
be raised (otherwise, there would be no reason
for not allowing the program to proceed
normally).
Program: "I am a liar.">
Is it?

(To be or not to be, that's the question!)
Extended numeric sets are proven to be mathematically correct and deliver> >> far safer and efficient computations than ones defined on bound numeric> >> subsets. NaN is a *legal* value of IEEE float.> >
(So what?)> >
I fail to see suitable uses of a NaN number ("Not-a-Number" number)> > other than to express an error within the number representation,>
It is the same misunderstanding as above. NaN is not an error, it is not a> number.

As I said before, in 99.9...9% of the uses of the inverse(0) function
it will be the result of a programming error (regardless of NaN).
It is like i=sqrt(-1), which is also not a [real] number, but an> ideal from another set [of complex numbers.]

It is not like complex numbers, because to my knowledge
there is no practical use for NaN (other than error
signaling, for which there is a much better programming
tool: exceptions).

In R, I agree with you that the problem is the same in both
situations: a programming error (located in the caller).
but - by all means - be free to use that defensive approach to> > inverse [inverse(0) = NaN].>
IEEE floats don't form a ring. So the theorem above does not hold. So what?>
Just don't forget that the inverse function (as all functions) are> > is not an end in it selves, but a mean to reach somewhere.> > I'll bet that in 99.99...99% if the times the client of inverse> > is not expecting to divide by zero, neither such result makes> > any sense to whatever calculation required the use of this> > function.>
That does not influence program correctness. A nice thing about ideals,> like NaN, is that they don't leak. If an algorithm is correct in R without> ideals it stays in R with ideals. So it is 100% safe. You can continue with> NaN to the point where R is needed. Note, not as a precondition, but as a> type conversion. This conversion will raise an exception for NaN. That> would be a correct behavior.

So you agree with me that the appropriate (exceptional) behavior
as a result to a use of NaN would be to raise an exception?

(We are getting somewhere.)

Of course in my opinion, the error source is not due to the use of
NaN. It is due to the part of program that was responsible for its
existence (but that just my opinion).
Now that's a *real* precondition.> >>>
What do you mean by "real"?> >>
= used to determine correctness of the program.> >
What?> >
Are you saying that the non-zero x precondition> > of inverse is not useful to determine the correctness> > of a program?>
No. I claim that only one of the following two statements is true for a> given program:>
1. A predicate is a "real" precondition <=> determines correctness => its> value is not used (handled) by the program>
2. A predicate is not a precondition => its value can be handled.

So you prescribe a defensive programming technique when
your compile time tools are unable to prove the correctness
of preconditions (and what about other assertions?),
even when it would be trivial to use them at runtime
as in DbC?

(Fine, just don't call it DbC.)
(Surely you are not stating that runnable> >>> preconditions are not real!)> >>
That is the only possibility, as I have shown in our previous discussion.> >
(I missed that demonstration.)>
pre: true> function Liar return Boolean is> begin> return not Correct (Liar);> end Liar;> post : Liar
If things determining the program correctness were allowed for evaluation> in the program, that would allow construction of the liar paradox.

That's the problem of searching for total correctness
(or the "truth" in science)

The much more practical and non-paradoxal search for incorrect
programs is much easier (as it is to search for incorrect scientific
theories).
So if a precondition determines correctness,

A precondition (or any other assertion) states a
correctness condition. It does not prove, by itself,
the correctness of a program (it is a mean, not an
end).
then it cannot be checked (=it> is "real"). If it is checked [and the system is not self-contradictory],> then it does not determine the correctness => it is not a precondition.

Runnable assertions cannot fully assert program correctness
(for the nth+2 times). They allow the detection of *incorrect*
programs (if, and only if, the assertion happens to be false
somewhere during program execution).

A runnable precondition is a practical approximation
of the formal mathematical precondition expected to
be observed. It cannot prove program correctness.
It can, nevertheless, detect program incorrectness
(why is this so difficult to understand?).
If that is your opinion, then don't call it DbC, or else you> > will be confusing everyone who does not know what is> > this methodology.>
So in your opinion the "real" DbC is self-contradictory?­

No.

(A reference for your real "DbC" would be most welcomed,
so that we may communicate with each other.)
Cool!>
--> Regards,> Dmitry A. Kazakov> http://www.dmitry-k­azakov.de

Best regards,

-miguel

--
Miguel Oliveira e Silva

Add comment
Martin Brown 1 March 2006 12:14:46 permanent link ]
 Daniel T. wrote:> In article <du2530$jog$1@newsg­4.svr.pol.co.uk>,> Martin Brown <|||newspam|||@nezu­mi.demon.co.uk> wrote:>
Daniel T. wrote:
The precondition of course is that 'x != 0' however, thats an easy thing >>>to check, and as such one can define a particular output for that >>>condition:>>>
// returns NaN if x == 0>>>double inverse( double x ) {>>> return 1/x;>>>}>>
Although you could specify it to return a silent NaN that merely delays >>detecting a hard error and contaminates other possibly meaningful future >>calculations that use this NaN result.>>
Generating a trap in most cases would be preferable since it usually >>signifies a serious programming error when division by zero occurs.>
I have no problem with that, it's still a defined result.

More importantly it isolates the failing code and broken contract as
soon as is reasonably possible. There isn't much point in continuing a
calculation with a runtime lash up flying on a wing and a prayer.

Anything that uses the Nan becomes contaminated wasting time and money.
Your improved definition potentially breaks some code that might be >>expected to work algebraically since you can no longer satisfy the >>invariant property for the function inverse for all valid inputs.>>
x == inverse( inverse(x) )>>
whereas 0 != inverse( inverse(0)) under your definition.>>
And at present inverse(Nan) is also undefined.>
We'd have to define that as well I guess. "ensure inverse(NaN) == 0"

Why guess or use Nan at all when the hardware provides signed infinites?

It is a very bad idea. One perfectly reasonable use for signalling NaNs
in testing is to ensure that loading floating point numbers from
uninitiallised variables will generate an immediate error interrupt.

If you must allow inverse(0) it should return a signed Infinity (and
IEEE floating point defines them) and that is what most FP hardware does
by default but it also requests a zero divide interrupt unless masked.

Regards,
Martin Brown
Add comment


Dmitry A. Kazakov 1 March 2006 16:46:53 permanent link ]
 On Tue, 28 Feb 2006 18:57:15 GMT, Daniel T. wrote:
We'd have to define that as well I guess. "ensure inverse(NaN) == 0"

No. Consider:

NaN = NaN * 0

Inverting both sides (we have an inverse now) and assuming that * and / are
associative and distributive:

1/NaN = 1/NaN * 1/0 <=>

0 = 0 * NaN <=>

0 = NaN (oops!)

Multiplicative inverse cannot be saved this way because NaN / NaN is not 1.

--
Regards,
Dmitry A. Kazakov
http://www.dmitry-k­azakov.de
Add comment
Daniel T. 1 March 2006 17:10:27 permanent link ]
 In article <4404E104.CA725428@­det.ua.pt>,
Miguel Oliveira e Silva <mos@det.ua.pt> wrote:
"Daniel T." wrote:>
In article <4404AB97.37B38F68@­det.ua.pt>,> > Miguel Oliveira e Silva <mos@det.ua.pt> wrote:> >
As in, "a require clause will cause an exception if its condition is> > false." This is very different from what happens if a precondition is> > not met.>
What do you propose that should happen in such situations?

When a require clause's condition is false, it should throw an
exception, because that is what require clauses are defined to do. I
would never propose that a well defined construct do anything other than
what it is defined to do.

When a precondition is not met, we cannot propose anything because (as
you agree to below,) we cannot even consider the behavior of the code.
If a precondition is not met, the behavior of the code cannot even be> > considered...>
Agreed. The program is incorrect (the error is somewhere within> the caller's code).

Funny, you agree that "if a precondition is not met, the behavior of the
code cannot even be considered", yet you spend a lot of bandwidth
considering what the behavior of the code should be when a precondition
is not met...

That's what I mean when I talk about "real" preconditions, as opposed to
Eiffel's pseudo-precondition­s that really aren't because they have
defined behavior. Please understand, I'm not deriding Eiffel here, I
think it is good to limit preconditions precisely because we can't
reason about the behavior of programs when they are not met (and we need
to be able to reason about the behavior of our programs.)
Here, I've been talking about real preconditions, ones that> > require being met or we cannot determine the outcome.>
All preconditions (postconditions, invariants and other assertions)> are required to be met in correct programs. So I think I've been> talking about the same things.>
DbC prescribes a very simple and precise behavior.> If you have alternative practical proposals -based on> the mathematical foundations in which most likely> we all agree- I'm all ears.

And therein lies the rub. "the behavior cannot even be considered" (you
know, that part you agreed to above?) means there is no solution, nor
can we even consider one.

As such we must do our best to remove preconditions in our code and
provide well defined results for anything detectable. Eiffel does this
by creating a postcondition, "if a parameter is a certain value an
exception will be raised." I'm fine with that, it's a great idea, but it
isn't a precondition (which is a good thing, because preconditions are
bad.)


--
Magic depends on tradition and belief. It does not welcome observation,
nor does it profit by experiment. On the other hand, science is based
on experience; it is open to correction by observation and experiment.
Add comment


Daniel T. 1 March 2006 17:26:54 permanent link ]
 In article <7fyp5pt4hnq7.1jec4­c7748d0u$.dlg@40tude­.net>,
"Dmitry A. Kazakov" <mailbox@dmitry-kaz­akov.de> wrote:
Note also that the correct theory gives you much more, than you think. It> tells that run-time checks are the behavior [of the thing doing the> checks.] This is a very valuable knowledge, which instructs developers to> publish the checks in the contract. It also gives a rationale for layered> fault-tolerant software design with layers insulated against faults> underneath. Exactly because you cannot do much for correctness within one> layer. This is IMO *true* Design by Contract!

Careful there, "Design by Contract" is trademarked, there is only One
True DbC.


--
Magic depends on tradition and belief. It does not welcome observation,
nor does it profit by experiment. On the other hand, science is based
on experience; it is open to correction by observation and experiment.
Add comment
Oliver Wong 1 March 2006 17:57:35 permanent link ]
 "Miguel Oliveira e Silva" <mos@det.ua.pt> wrote in message
news:4404D2B9.17646­3A5@det.ua.pt...> Oliver Wong wrote:>
What if the contract specifically states that the behaviour of a >> given>> method is to raise an exception?>
I understand what you Daniel and Dmitry are trying to> argue in this point. But as I several times attempted to call> up to your attention, DbC(tm) has a much simpler view of> contracts, normal program behavior and exceptions.> In DbC exceptions are simply the response of a program> to an incorrect behavior due to a broken contract.>
There is no need to put exceptions in contracts, because> in DbC when a runnable assertions is false an exception> is required to be raised.>
You may argue that exceptions can be used in normal> program control flow (in Eiffel its much harder to do that,> because, unlike Ada/C++/Java its exception mechanism> is tightly bound to DbC). However, I must insist that> such use is inappropriate (even in those languages).> Not only normal conditional instructions are much> more safe, expressive and efficient, but also it mixes> up two different programming worlds: the one bound> to the expected normal behavior of programs, and the> one used to get along with exceptional incorrect behavior.>
Also using exceptions for normal program control,> is little more than the disguise use of the unstructured> goto instruction (no more single point of entry and> single point of exit for program components).

From my perspective, you have a view of "this is good enough for me, so
it should be good enough for everyone". When I mentioned that testing the
pre-conditions could break runtime performance requirements of a method, you
said something along the lines of 99.99999% of programs are not real-time
systems, and runtime performance isn't important except for real-time
systems, for example. So I'm going to provide a few examples, but I fear
you'll simply dismiss them as "well, these don't apply 99.99999% of the
time."

I think sometimes raising exceptions is a very legitimate part of the
behaviour of a program, and not merely constrained to indicating incorrect
programs. For example, let's say I'm writing a modular program which can
accept plugins written by 3rd parties. I want to ensure that if the plugins
screw up and throw exceptions, this doesn't bring down my whole application.

Let's say I'm writing a unit testing framework (e.g. jUnit), I might
create a method whose sole purpose is to throw an exception (e.g.
assert[anything]()), so the exception is very much part of the normal
behaviour of the program as well. Example:

/*
Pre-conditions: objects A and B implement an appropriate isEqual method.
Post-condition: Throws an exception if A.equals(B) is false, or if exactly
one of the objects is null.
*/
assertEquals(Object­ A, Object B) {
if (A == null) {
if (B == null) {
return;
}
throw new AssertionException(­);
}
if (B == null) {
throw new AssertionException(­);
}
if (A.equals(B)) {
return;
}
throw new AssertionException(­);
}

- Oliver

Add comment


Oliver Wong 1 March 2006 18:04:41 permanent link ]
 
"Dmitry A. Kazakov" <mailbox@dmitry-kaz­akov.de> wrote in message
news:7fyp5pt4hnq7.1­jec4c7748d0u$.dlg@40­tude.net...
Note that double (assuming IEEE float) and, say, DEC floating-point type,> are different types with different sets of values! It is *incorrect* to> raise an exception for double 1/x because 1/0 is *defined* to return NaN> for 1/0. Defined here, is in strict mathematical sense. If you take > another> type, with the domain set limited to only real numbers (like DEC> floating-point is), then exception would be appropriate.

I didn't bring this up earlier, 'cause it didn't seem like an important
point, but since this example is being quoted, paraphrased, repeated, etc.
all over this thread, I figure I should say it now.

I think 1/0 is defined by IEEE to be equal to positive infinity, not
NaN.

(negative) infinity divided by (negative) infinity is equal to NaN.
Maybe infinity minus infinity is also NaN, but I'm not sure about this last
one.

- Oliver

Add comment
Oliver Wong 1 March 2006 18:08:54 permanent link ]
 
"Miguel Oliveira e Silva" <mos@det.ua.pt> wrote in message
news:4404ED6B.CFB97­53E@det.ua.pt...> "Dmitry A. Kazakov" wrote:
What could an *incorrect*>> program *correctly* do about anything?>
Terminate execution (identifying the error);> or propagate the exception upwards in the> call stack until a point in which it would be> safe to retry an alternative (hopefully, correct)> algorithm (fault tolerance).

You seem to be missing the point here. The program is incorrect. So you
look at the source code, and somewhere, it contains bugs, but you're not
sure where yet. You look at the source code, and you *THINK* what it will do
is terminate execution or propagate the exception upwards in the call stack
until a point in which it would be safe to retry an alternative algorithm...
but maybe it won't! Why not? Because it's incorrect!

This is what is meant by "You cannot say anything about the behaviour of
an incorrect program." You might WANT it to terminate; but it won't
nescessarily do so!

- Oliver

Add comment
Miguel Oliveira e Silva 1 March 2006 18:32:12 permanent link ]
 "Daniel T." wrote:
(...)
If a precondition is not met, the behavior of the code cannot even be> > > considered...> >
Agreed. The program is incorrect (the error is somewhere within> > the caller's code).>
Funny, you agree that "if a precondition is not met, the behavior of the> code cannot even be considered",

When a precondition fails, it is useless to think about the normal
behavior of programs (that was what I though you were referring to).
As I said too many times, the program is incorrect, hence it should
not run, or else appropriate exceptional behavior is desirable and
even required if the faulty precondition was detected at runtime.

(You seem to be concerned about a pure theoretical concept of
preconditions with little practical use when our static verification
tools are unable to prove their correctness. I am concerned
about how we can approximate them in practical programming
to help us build more reliable programs.)
yet you spend a lot of bandwidth> considering what the behavior of the code should be when a precondition> is not met...

(... normal versus exceptional ...)

Another thing that puzzles me, is why do you keep arguing that
runnable preconditions are not preconditions just because
they do what is required to be done when an incorrect program
is detected?

They are not (obviously) proved preconditions. Nevertheless
they are a practical approximation of the desirable behavior,
and sometimes they even express the expected formal
condition (equal to its pure mathematical counterpart).
Of course they cannot prove program correctness at
runtime, they can, nevertheless, correctly detect some
incorrect programs (which is a huge contribution
to approximate correctness and to produce quality
reliable software).

Also you seem to consider, for some reason, that exceptions are
part of normal program behavior (reason why you insist in not
fully understanding what I'm saying). That, in my opinion (and in
DbC's), is a basic misunderstanding of this mechanism.
Its existence is exactly to allow us to think and use two
separated worlds: normal program behavior and exceptional
behavior. In the former our primary objective is to reach
correctness. The latter aims at robustness, either for a
faster detection of errors and their correction, or for
implementing fault tolerant techniques.
(...)
Eiffel's pseudo-precondition­s that really aren't because they have> defined behavior.

A precondition is a condition expected to be observed
before the routine starts its execution. Eiffel require clauses
*are* preconditions (such as ensure clauses are postconditions
and invariant clauses are invariants).
Please understand, I'm not deriding Eiffel here, I> think it is good to limit preconditions precisely because we can't> reason about the behavior of programs when they are not met (and we need> to be able to reason about the behavior of our programs.)>
Here, I've been talking about real preconditions, ones that> > > require being met or we cannot determine the outcome.> >
All preconditions (postconditions, invariants and other assertions)> > are required to be met in correct programs. So I think I've been> > talking about the same things.> >
DbC prescribes a very simple and precise behavior.> > If you have alternative practical proposals -based on> > the mathematical foundations in which most likely> > we all agree- I'm all ears.>
And therein lies the rub. "the behavior cannot even be considered" (you> know, that part you agreed to above?) means there is no solution, nor> can we even consider one.>
As such we must do our best to remove preconditions in our code and> provide well defined results for anything detectable.

No.
Eiffel does this by creating a postcondition,

No it doesn't.
"if a parameter is a certain value an> exception will be raised."

That is not part of the postcondition (how could it
be if the routine did not start its execution!).
It is the exceptional behavior as a result of a failed
precondition.
I'm fine with that, it's a great idea, but it> isn't a precondition

Of course it is. It was a condition expected
to be verified by the client *before* (as in *pre*)
the routine starts its execution. In this respect,
it is irrelevant if the error was found statically
or at runtime.

(References please.)
(which is a good thing, because preconditions are bad.)

?

Preconditions, postconditions, invariants and other
assertions are good. They make it quite clear
what are the contracts expected, and they give
us an idea of the meaning of programs (reusing
Floyd's article title).
--> Magic depends on tradition and belief. It does not welcome observation,> nor does it profit by experiment. On the other hand, science is based> on experience; it is open to correction by observation and experiment.

Best regards,

-miguel

--
Miguel Oliveira e Silva


Add comment
Dmitry A. Kazakov 1 March 2006 19:15:52 permanent link ]
 On Wed, 01 Mar 2006 15:04:41 GMT, Oliver Wong wrote:
I didn't bring this up earlier, 'cause it didn't seem like an important > point, but since this example is being quoted, paraphrased, repeated, etc. > all over this thread, I figure I should say it now.>
I think 1/0 is defined by IEEE to be equal to positive infinity, not > NaN.

You are right.

Positive / 0 = +Infinity
Negative / 0 = -Infinity
0/0 = NaN.

NaN is would be OK (in fact for any operation. I think it is called Quiet
NaN, QNaN), but +Infinity is much better.
(negative) infinity divided by (negative) infinity is equal to NaN. > Maybe infinity minus infinity is also NaN,

Yes.

--
Regards,
Dmitry A. Kazakov
http://www.dmitry-k­azakov.de
Add comment
Bjorn Reese 2 March 2006 00:54:29 permanent link ]
 Daniel T. wrote:
// returns NaN if x == 0>>>double inverse( double x ) {>>> return 1/x;>>>}

Returns positive infinity, not NaN.
We'd have to define that as well I guess. "ensure inverse(NaN) == 0"

Returns NaN, not 0.

The above assumes IEEE 754.

--
mail1dotstofanetdot­dk
Add comment
Dmitry A. Kazakov 2 March 2006 23:27:57 permanent link ]
 On Thu, 02 Mar 2006 15:43:30 +0000, Miguel Oliveira e Silva wrote:
That's where he is wrong. You see, in your workaround runnable assertion> the precondition is correctly putted *before* the routine starts the execution> of its hopefully useful algorithm. If I call "foo" in (C++/Java) without a> try/catch block the exception will pass by me (without I'm being aware of it).> Hence:>
// somewhere in a program> do_x;> r = foo(s);> do_y(r);>
before "do_y" the assertion that this code ensures is the postcondition> of "foo", which -in order for the program not to be incorrect- should> ensure do_y's precondition.

Not quite. r = foo(s) ensures a conjuction of preconditions. One part is
the precondition of do_y, another is a conjuction of the preconditions of
all enclosing catch-blocks.

Consider:

try
{
do_x;
r = foo(s);
post: r /= null V NullStringException­= P1
pre: r /= null= P2
do_y(r);
post ...
}
post: ... V NullStringException­
catch (NullStringExceptio­n)
pre: NullStringException­= P3
{
...
}

P1 => P2 V P3. It's fine.

--
Regards,
Dmitry A. Kazakov
http://www.dmitry-k­azakov.de
Add comment
Guest 3 March 2006 14:16:34 permanent link ]
 Oliver Wong wrote:

[ Design By Contract saga snipped, but acknowledged ]
It's bad for the supplier because he cannot get any clients to use it.> What's the point of creating a method if it will never be used? It's wasted> effort on the supplier's part.
But I guess it's useless to proceed further with this until we define> metrics for "good" and "bad" for the supplier and client.
It is GOOD for the client if he can find an implementation of a contract> which solves his problem without imposing too many pre-conditions.
It is GOOD for the supplier if he can find a client who will agree to a> contract with the supplier.

The best components from the users' viewpoint are those that have the
weakest preconditions and strongest post/invariant conditions.

The suppliers' viewpoint is the converse.

Within those extremes we have a dynamic where components arrive at
contracts that are amenable to both (usage, implementation effort etc)
.

Hence the term *contract* . Contracts are negotiated are they not ...


Regards,
Steven Perryman

Add comment
Oliver Wong 3 March 2006 20:22:42 permanent link ]
 
<ggroups@bigfoot.co­m> wrote in message
news:1141384594.168­474.257720@z34g2000c­wc.googlegroups.com.­..> Oliver Wong wrote:>
[ Design By Contract saga snipped, but acknowledged ]>
It's bad for the supplier because he cannot get any clients to use it.>> What's the point of creating a method if it will never be used? It's >> wasted>> effort on the supplier's part.>
But I guess it's useless to proceed further with this until we define>> metrics for "good" and "bad" for the supplier and client.>
It is GOOD for the client if he can find an implementation of a contract>> which solves his problem without imposing too many pre-conditions.>
It is GOOD for the supplier if he can find a client who will agree to a>> contract with the supplier.>
The best components from the users' viewpoint are those that have the> weakest preconditions and strongest post/invariant conditions.>
The suppliers' viewpoint is the converse.>
Within those extremes we have a dynamic where components arrive at> contracts that are amenable to both (usage, implementation effort etc)> .>
Hence the term *contract* . Contracts are negotiated are they not ...

The problem with this is that if it were true that it's best for the
supplier to implement components with the strongest pre-conditions and the
weakest post-conditions, then no one would ever implement any component
except for this one:

/*
pre-condition: false.
post-condition: does nothing
*/
void doesNothing() {
}

But why isn't that what we observe in real life? Because there's an
ADDED factor that a supplier will not want to waste his/her time
implementing a component that no one wants to use! That's the point I was
trying to make.

- Oliver

Add comment
Dmitry A. Kazakov 3 March 2006 21:07:35 permanent link ]
 On 3 Mar 2006 03:16:34 -0800, ggroups@bigfoot.com­ wrote:
Oliver Wong wrote:>
[ Design By Contract saga snipped, but acknowledged ]>
It's bad for the supplier because he cannot get any clients to use it.>> What's the point of creating a method if it will never be used? It's wasted>> effort on the supplier's part.>
But I guess it's useless to proceed further with this until we define>> metrics for "good" and "bad" for the supplier and client.>
It is GOOD for the client if he can find an implementation of a contract>> which solves his problem without imposing too many pre-conditions.>
It is GOOD for the supplier if he can find a client who will agree to a>> contract with the supplier.>
The best components from the users' viewpoint are those that have the> weakest preconditions and strongest post/invariant conditions.>
The suppliers' viewpoint is the converse.>
Within those extremes we have a dynamic where components arrive at> contracts that are amenable to both (usage, implementation effort etc)>
Hence the term *contract* . Contracts are negotiated are they not ...

Maybe, but there is also somebody who assigns suppliers and consumers,
responsible for the problem decomposition. Now the question is, when the
negotiation takes place. Before or after the roles have been identified?

--
Regards,
Dmitry A. Kazakov
http://www.dmitry-k­azakov.de
Add comment
Miguel Oliveira e Silva 3 March 2006 21:13:15 permanent link ]
 "Dmitry A. Kazakov" wrote:
On Thu, 02 Mar 2006 15:43:30 +0000, Miguel Oliveira e Silva wrote:>
That's where he is wrong. You see, in your workaround runnable assertion> > the precondition is correctly putted *before* the routine starts the execution> > of its hopefully useful algorithm. If I call "foo" in (C++/Java) without a> > try/catch block the exception will pass by me (without I'm being aware of it).> > Hence:> >
// somewhere in a program> > do_x;> > r = foo(s);> > do_y(r);> >
before "do_y" the assertion that this code ensures is the postcondition> > of "foo", which -in order for the program not to be incorrect- should> > ensure do_y's precondition.
Not quite. r = foo(s) ensures a conjuction of preconditions.

You assume that exceptions raised due to false preconditions,
disguised as a postcondition, are part of a correct program.
I do not (is this reasonable to you?).
One part is> the precondition of do_y, another is a conjuction of the preconditions of> all enclosing catch-blocks.>
Consider:>
{> do_x;> r = foo(s);> post: r /= null V NullStringException­ = P1> pre: r /= null = P2> do_y(r);> post ...> }> post: ... V NullStringException­> catch (NullStringExceptio­n)> pre: NullStringException­ = P3> {> ...> }>
P1 => P2 V P3. It's fine.

Correct.

My point, is that P3 is not part of "do_y"'s precondition
(an exception is never a precondition of normal
routines/instructio­ns, only for catch/rescue blocks).

So I was using a "reductio ad absurdum"
argument, in which I attempted to show
that exceptional behavior (being goto like)
is outside normal structured (single entry
and exit points) view of programs.

So, exceptions are required to take into
consideration code outside normal
program structured instructions
(as you did, by including a possible
catch block). Using them for normal
program behavior is not a structured
approach, hence it makes it much
harder to reason on program
correctness.
--> Regards,> Dmitry A. Kazakov> http://www.dmitry-k­azakov.de

Best regards,

-miguel

--
Miguel Oliveira e Silva

Add comment
Oliver Wong 3 March 2006 21:32:06 permanent link ]
 
"Miguel Oliveira e Silva" <mos@det.ua.pt> wrote in message
news:44087328.68DFA­1A7@det.ua.pt...> Oliver Wong wrote:

[snipped everything except Contract-A and contract-B, which seems to be the
core issue now]
There's is no disagreement here. I'm just saying there exist a >> mapping>> from contract A to contract B, where A has one or more pre-condition, and>> contract B has fewer pre-conditions, such that any client who accepts A >> will>> be willing to accept B as well.>>
E.g.:>>
/*>> Contract A:>> Pre-condition: s is never null.>> Post-condition: returns s.>>
Contract B:>> Pre-condition: none.>> Post-condition: if s is null, throws NullPointerExceptio­n; otherwise,>> returns s.>> */>>
Any client who accepts contract A here, should also be willing to >> accept>> contract B. From his perspective, they do the same thing.>
In contract B the precondition should have been the same> as in A: (s != NULL).> You just made the mistake to hide it inside the postcondition> (wrongly making the clients belief that the routine can do> useful work regardless of the value of s).

Whether something is "useful" or not depends on the client's opinion.
Perhaps the client specifically wants a NullPointerExceptio­n (and not ,
e.g., AssertionException)­ to be thrown when s is equal to null, and
therefore B is MORE useful than A.

A does not specify what will happen if s is null. If the client is
writing code which critically depends on NullPointerExceptio­n being thrown
when s is null, then the client MUST use B, and CANNOT use A.

If the client will never set s = null, the nthe client can use either B
or A, as they will both perform identically for all situations the client
will encounter.

That is why I say any client who accepts contract A will also accept
contract B.
Contract B, is much (much) worse than A's because,> if s happens to be NULL, the client is not ensured (since> the exceptional behavior is in the postcondition) that> the routine did not do nothing else besides raising an> exception. Hence he may lose the extremely important> guarantee that the supplier object invariant is still correct> even if the exception was raised (DbC ensures that).> That's a very (very) serious problem resulting> from putting the (exceptional) behavior of broken> preconditions inside postconditions.

This is a problem with all contracts: post conditions generally don't
list all the things they DON'T do. E.g.:

/*
Pre-condition: None.
Post-condition: Returns true. Does not emit anything to standard out. Does
not allocate RAM. Does not kill children. Does not cause your car to
explode. Etc.
*/
bool getTrue() {
return true;
}

Usually, if a contract does not mention behaviour Foo, it can safely be
assumed that the method will NOT do contract Foo. If this is a problem for
the client, the client should negotiate a new contract where the desired
behaviour is made explicit.

Contract B says that the method will return s except when s is null, in
which case it will throw NullPointerExceptio­n. Note that the post-condition
does not say things like "BTW, I am free to violate any class constraints,
etc." And because it doesn't say that, it won't do that.

Exceptions do not indicate that class invariants might have been
violated. This fear is unjustified.
Another serious problem with B's like contracts> happens when the programmer misses an> exceptional behavior in postconditions for> some runnable (hidden) precondition.> The client knows that such a precondition> exists, but he will be unsure if the supplier> will indeed respond with an exception.> Isn't it much simpler to take that for> granted as in DbC (without moving> assertions to wrong places)?

There is NO pre-condition in contract B. Not even a hidden one. I don't
know why you say there is. If the client "knows" that such a pre-condition
exists, then that client has obviously misunderstood the contract. There is
not pre-condition.

If the client carefully reads the contract, he will see that the
behaviour of the method is to return s when s is not null, and to throw
NullPointerExceptio­n when s is null.

The client therefore knows the behaviour of the method in the cases
where s = "Dog", s = "Hello World!", s = null, and an just about every other
situation that will arise. The behaviour is explicitly stated in the
contract.
Tell me, why do you put exceptional behavior> inside postconditions, and not inside preconditions?> (Which would bring your normal *and* exceptional> behavior to match DbC.)

Contract A and contract B describe two different behaviours. If I want
the behaviour of contract B, I must use contract B. I cannot use contract A,
because it (might) do something different than contract B.

The original claim up thread is that all contracts with runnable
pre-conditions that are accepted by a given client can be converted into
another contract with fewer (possibly zero) pre-conditions which will also
be accepted by a client.

The reverse is not nescessarily true.
Afterall, the exception was caused by something> that the client did (s=NULL), and not as a result> of something inside the supplier's code. (Do we> agree in this point?)

No, I'm not sure that we are in agreement. When you talk about "cause",
it can get philosophical too:

A: "Why was this exception thrown?"
B: "Because there's a throw clause in the supplier's code."
A: "Why is there a throw clause in the supplier's code?"
B: "So that the code satisfies the contract given."
A: "Why is the contract written the way it is written?"
B: "Because that's what the client and the supplier agreed upon."
etc.
Again, DbC approach is much simpler and safe:> any detected false assertion raises an exception.

This sentence does not nescessarily imply that ALL raised exceptions are
caused by a detected false assertion.

- Oliver

Add comment
Dmitry A. Kazakov 3 March 2006 21:46:03 permanent link ]
 On Fri, 03 Mar 2006 18:13:15 +0000, Miguel Oliveira e Silva wrote:
You assume that exceptions raised due to false preconditions,> disguised as a postcondition, are part of a correct program.> I do not (is this reasonable to you?).

No. In my view a run-time precondition [a real one] if evaluated, then that
shall happen on an independent context. So exception propagation would be
wrong. Exception is a synchronous transfer of control. Failed precondition
shall perform asynchronous transfer of control (ATC.) Like hardware
interrupts do. Ada has software ATCs. Anyway, after an ATC any continuation
on the context caused ACT is impossible. Basically it is an abort, this the
only way real preconditions might be checked at run-time - by an
*independent* system. The states of that system are not ones of the
monitored system.
My point, is that P3 is not part of "do_y"'s precondition> (an exception is never a precondition of normal> routines/instructio­ns, only for catch/rescue blocks).

Yes.
So I was using a "reductio ad absurdum"> argument, in which I attempted to show> that exceptional behavior (being goto like)> is outside normal structured (single entry> and exit points) view of programs.

Sort of. It is like jumping out of a loop. It might become very nasty when
misused. Still exceptional behavior is a behavior. Program error is not.
So, exceptions are required to take into> consideration code outside normal> program structured instructions> (as you did, by including a possible> catch block). Using them for normal> program behavior is not a structured> approach, hence it makes it much> harder to reason on program> correctness.

They need better language support. For example, Java's contracted
exceptions is a great idea, though, maybe, poorly implemented. When
considered as a part of the contract, exceptions can be statically checked.
This definitely requires language designers to do some homework. But if
done properly, it should allow building much safer fault-tolerant systems.
Did you saw a program which can really recover after a storage allocation
fault?

--
Regards,
Dmitry A. Kazakov
http://www.dmitry-k­azakov.de
Add comment
Miguel Oliveira e Silva 4 March 2006 20:17:10 permanent link ]
 "Dmitry A. Kazakov" wrote:
On Fri, 03 Mar 2006 18:13:15 +0000, Miguel Oliveira e Silva wrote:>
You assume that exceptions raised due to false preconditions,> > disguised as a postcondition, are part of a correct program.> > I do not (is this reasonable to you?).>
No. In my view a run-time precondition [a real one] if evaluated, then that> shall happen on an independent context.

Well, in DbC -although both worlds share the program state- the
exceptional world should be taken as being separated from the
normal world (this has been one of my main "fights" in this thread).
That is why we should never use exceptions to do normal useful
work in programs (using exceptions as goto's).
So exception propagation would be> wrong.

Wrong would be to not propagate exceptions when a false
assertion is detected.
Exception is a synchronous transfer of control.

A very important property for assertions, as it ensures
nothing else happens in the program state (no attempt
to write in arrays outside their boundaries, etc.)
after its failure.
Failed precondition> shall perform asynchronous transfer of control (ATC.)

(Do you mean that the program is allowed to
continue after such failure?)

What if, in the program being monitored, a false
precondition was detected in a routine which
launches a nuclear missile?

The synchronous internal exceptional behavior
is essential (regardless of possible external
concurrent, synchronous or asynchronous,
entities).

On the other hand, to detect false assertions one
is required to observe the programs internal state.
That is what assertions do.

Nothing prevent you from having external independent
entities to redundantly approach that monitoring
behavior, but it is essential that inside programs
a false detectable assertions is taken care of
in the right place (where the assertion applies,
so in the case of preconditions: before the
routine starts its execution, and not in
postconditions).

As I said, in DbC, assertions not only allow a precise and
correct (although not complete) error detection, but they
also prevent that nasty things happen to the program state
(out of bound accesses to array, etc.). So, many times we can
recover safely from a broken exception. If not, then
not only the program aborts, but also, with DbC
assertion mechanism, it may also precisely
inform the outside world what has happened, thus
allowing a more precise program replacement.
Like hardware> interrupts do. Ada has software ATCs. Anyway, after an ATC any continuation> on the context caused ACT is impossible.

So the failed program behavior is synchronous after all.
It stop immediately. Are ATC's an exception
mechanism to outside concurrent entities?

Exception are a similar internal thing. They stop normal
program execution, passing the control to the separated
exceptional world (we don't disagree that much in this
regard).
Basically it is an abort, this the> only way real preconditions might be checked at run-time - by an> *independent* system.

I've already showed you that is not true (you take a very
extreme outside view of programs, as if programs could
not know nothing of themselves!). A correctly placed
precondition prevents the program to harm itself.
Hence its state remains quite trustable.

It is trivial to test inumerous real preconditions
when a program is executing (non negative square
roots, etc.). That does not mean, of course,
that *all* preconditions can always be safely
tested. In such cases I agree with you that
it is important to rely on outside independent
entities (protected by process alike runtime
boundaries).

But, Dmitry, to pick in such *particular*
cases and generalize them to *all* cases
as you are doing, is simply absurd.
The states of that system are not ones of the> monitored system.

That is good, because they are protected.

That, however, does not rule out the
inumerous cases in which the states can
be safely shared.
My point, is that P3 is not part of "do_y"'s precondition> > (an exception is never a precondition of normal> > routines/instructio­ns, only for catch/rescue blocks).>
Yes.>
So I was using a "reductio ad absurdum"> > argument, in which I attempted to show> > that exceptional behavior (being goto like)> > is outside normal structured (single entry> > and exit points) view of programs.>
Sort of.

Either it is, or it isn't!
It is like jumping out of a loop.

And isn't that exactly what I'm saying (goto like)?
It might become very nasty when misused.

Of course. Structured programming should
be part of the formation of all programmers.
Still exceptional behavior is a behavior. Program error is not.

Exceptional behavior is the behavior a incorrect program
should take. Then, either the program is unable to cope
with the failure and exceptions are propagated until
the final abortion of the program (nothing stops
another program to take its place as you suggest);
or else somewhere in between the program is
able to safely replace the faulty code (avoiding
a new "big-bang").
(...)
--> Regards,> Dmitry A. Kazakov> http://www.dmitry-k­azakov.de

-miguel

--
Miguel Oliveira e Silva

Add comment
Dmitry A. Kazakov 4 March 2006 23:26:36 permanent link ]
 On Sat, 04 Mar 2006 17:17:10 +0000, Miguel Oliveira e Silva wrote:
"Dmitry A. Kazakov" wrote:>
On Fri, 03 Mar 2006 18:13:15 +0000, Miguel Oliveira e Silva wrote:>>
You assume that exceptions raised due to false preconditions,>>> disguised as a postcondition, are part of a correct program.>>> I do not (is this reasonable to you?).>>
No. In my view a run-time precondition [a real one] if evaluated, then that>> shall happen on an independent context.>
Well, in DbC -although both worlds share the program state- the> exceptional world should be taken as being separated from the> normal world (this has been one of my main "fights" in this thread).

Yes, this is the crucial point of disagreement. A program cannot be correct
in one of its states and incorrect in another. Correctness applies to all
possible states of a given program. So any shared states don't count.
That is why we should never use exceptions to do normal useful> work in programs (using exceptions as goto's).

We should. The use case of exception is when the implementation logic
sufficiently deviates for some program states. These states are usually
called exceptional, but this does not attribute the program correctness,
but merely the states. A typical example is, when decomposition prevents
handling of some situations in definite contexts.

For instance, when Read determines file end it raises an exception. Read
cannot and should not handle file end. It does not have the information
necessary for it. To give this information to Read, would be a very fragile
design. So the design decision is to handle this state outside Read. This
does not make Read or finite files incorrect. Note that a return code for
Read would do exactly same, but much less safer and efficient. It is not an
alternative.
Exception is a synchronous transfer of control.>
A very important property for assertions, as it ensures> nothing else happens in the program state (no attempt> to write in arrays outside their boundaries, etc.)> after its failure.

Exactly this could happen if the transfer is synchronous. Exception
propagation has side effects which change the state. Asynchronous transfer
does not have side effects. Which also implies that there is no reasonable
way to continue the aborted thing.
On the other hand, to detect false assertions one> is required to observe the programs internal state.> That is what assertions do.

Here we go again. To observe state /= to observe correctness. State
observation is a contracted behavior. Any program is just a FSM. And what a
FSM does? It observes its state and goes to another one.

That assertions indeed observe states is the point Daniel, Oliver and I are
defending. They don't check correctness.
Like hardware>> interrupts do. Ada has software ATCs. Anyway, after an ATC any continuation>> on the context caused ACT is impossible.>
So the failed program behavior is synchronous after all.> It stop immediately. Are ATC's an exception> mechanism to outside concurrent entities?

Technically it breaks at the first point where it can.
Exception are a similar internal thing. They stop normal> program execution, passing the control to the separated> exceptional world (we don't disagree that much in this> regard).

It only appears so. You can use anything you want for correctness checks,
if you can be sure that the program being checked does not influence one
that checks. Exceptions as they are implemented in all languages I know,
are unsuitable for this. ATCs, system traps, calls to supervisor are much
better. Physically separated systems are even more better.
Basically it is an abort, this the>> only way real preconditions might be checked at run-time - by an>> *independent* system.>
I've already showed you that is not true (you take a very> extreme outside view of programs, as if programs could> not know nothing of themselves!).

No. I only claim that a program cannot know anything about its correctness.
About itself, a program knows its state.
So I was using a "reductio ad absurdum">>> argument, in which I attempted to show>>> that exceptional behavior (being goto like)>>> is outside normal structured (single entry>>> and exit points) view of programs.>>
Sort of.>
Either it is, or it isn't!

The definition of structured programming isn't that formal. You cannot
point at a program and say whether it is well structured or not. There are
cases where gotos are better structured than if-then-else.
Still exceptional behavior is a behavior. Program error is not.>
Exceptional behavior is the behavior a incorrect program> should take.

[ Don't you see any problems with such statements? ]

A correct behavior of an incorrect program? Would an incorrect program
become correct by raising an exception? Was it incorrect before it raised
the exception? But it is definitely correct after doing that! Ah, maybe, it
was always correct except for a negligible period of time required to raise
an exception? Wouldn't be any program correct if we implemented it as:

procedure Foo is
begin
raise Oh_My_God;
end Foo;
Then, either the program is unable to cope> with the failure and exceptions are propagated until> the final abortion of the program (nothing stops> another program to take its place as you suggest);

Isn't is so, that any program is correct as long as it keeps on coping
with?

--
Regards,
Dmitry A. Kazakov
http://www.dmitry-k­azakov.de
Add comment
Kenneth P. Turvey 5 March 2006 03:23:35 permanent link ]
 -----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

On Fri, 03 Mar 2006 18:32:06 +0000, Oliver Wong wrote:
If the client will never set s = null, the nthe client can use either B > or A, as they will both perform identically for all situations the client > will encounter.

I should note that this isn't strictly true. Client B must do some work
to check to see if the constraint is violated. This may be a small amount
of work or a large amount of work, but it will take time. Client A will
get the same answer on every case in which it is defined and will perform
better than client B.

- --
Kenneth P. Turvey <kt-usenet@squeakyd­olphin.com>
Phone : (314) 255-2199

XMPP IM: kpturvey@jabber.org­
Yahoo IM: kpturvey2
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.1 (GNU/Linux)

iD8DBQFECi87i2ZgbrT­ULjoRArijAJ43kBosnnc­Z5GaZg0M4TZBXB/3SUwC­gnKgN
sGD5esbNw9JyP7/Xpo2­rcj0=
=j2NN
-----END PGP SIGNATURE-----

Add comment
Miguel Oliveira e Silva 5 March 2006 22:04:39 permanent link ]
 "Dmitry A. Kazakov" wrote:
On Sat, 04 Mar 2006 17:17:10 +0000, Miguel Oliveira e Silva wrote:>
"Dmitry A. Kazakov" wrote:> >
On Fri, 03 Mar 2006 18:13:15 +0000, Miguel Oliveira e Silva wrote:> >>
You assume that exceptions raised due to false preconditions,> >>> disguised as a postcondition, are part of a correct program.> >>> I do not (is this reasonable to you?).> >>
No. In my view a run-time precondition [a real one] if evaluated, then that> >> shall happen on an independent context.> >
Well, in DbC -although both worlds share the program state- the> > exceptional world should be taken as being separated from the> > normal world (this has been one of my main "fights" in this thread).>
Yes, this is the crucial point of disagreement. A program cannot be correct> in one of its states and incorrect in another.

The program as whole no (by definition).
But *parts* of it may (and most likely
are if the program is modular).

A flat tyre in my car does not affect its engine!
Correctness applies to all> possible states of a given program.

The total correctness of program, of course.
So any shared states don't count.

(Think again.)
That is why we should never use exceptions to do normal useful> > work in programs (using exceptions as goto's).>
We should. The use case of exception is when the implementation logic> sufficiently deviates for some program states. These states are usually> called exceptional, but this does not attribute the program correctness,

In DbC's programmers *choose* to use them (mainly)
for that purpose.
but merely the states.

And the *programmer* knows that some states show,
without doubt, program incorrectness (those in which
assertions are false). Hence he uses (in DbC) exceptions
to deal with that situation.
A typical example is, when decomposition prevents> handling of some situations in definite contexts.>
For instance, when Read determines file end it raises an exception.

I've already mentioned these group of problems.

A program should be ruthless in its internal contracts.
Since it it its own responsibility to ensure them. Hence
whenever an internal contract is broken (false assertions)
we are in the presence of a program error.

However, when dealing with external entities (whose
behavior cannot be controlled by the program), one
should use a defensive programming approach
(just because it may be normal that a program
expecting to read something out of a file, receives
a end-of-file. That is not a program error, it is
simply an external broken contract).

To implement this defensive behavior, one can,
mainly, use one of two approaches:

1. Normal control instructions.

Using your example, instead of "read" services,
one uses "tryToRead" services. A command-query
separated interface might look something like these:

class IO

feature

try_to_read_integer­ is
require
file_opened;
file_opened_to_read­;

last_read_successfu­l: BOOLEAN

last_read_was_an_in­teger: BOOLEAN

last_integer: INTEGER is
require
last_read_successfu­l;
last_read_was_an_in­teger

end_of_file: BOOLEAN

(...)

end -- IO

(As you can see, exceptions are not required for
normal behavior)


2. Use the exception mechanism.

Another possible approach (already mentioned in:

http://groups.googl­e.com/group/comp.obj­ect/tree/browse_frm/­thread/b9462e645bc47­98d/fcc473cb64842ae2­?rnum=21&_done=%2Fgr­oup%2Fcomp.object%2F­browse_frm%2Fthread%­2Fb9462e645bc4798d%2­F76f50acc016b1fbb%3F­tvc%3D1%26#doc_269e3­a59a5710360

) is to take an expected behavior from outside
entities as an external contract being broken.

This type of broken contracts, are much easier to
rectify because they are not the expression of
a program error.

--

All these being said, I still cannot understand your
point in this discussion.
Read cannot and should not handle file end. It does not have the information> necessary for it. To give this information to Read, would be a very fragile> design. So the design decision is to handle this state outside Read. This> does not make Read or finite files incorrect. Note that a return code for> Read would do exactly same, but much less safer and efficient. It is not an> alternative.

Agreed (but my num. 1 proposal is).
Exception is a synchronous transfer of control.> >
A very important property for assertions, as it ensures> > nothing else happens in the program state (no attempt> > to write in arrays outside their boundaries, etc.)> > after its failure.>
Exactly this could happen if the transfer is synchronous.

What?

Only if the programmer chooses to do a very bad thing
in catch blocks (to use Ada/C++/Java terminology).
Exception> propagation has side effects which change the state. Asynchronous transfer> does not have side effects. Which also implies that there is no reasonable> way to continue the aborted thing.

Really?

So in your opinion a new big-bang is *always* required.

(If I've used that strategy to my sixteen year old car,
I would have bought quite a few hundreds of
cars by now.)
On the other hand, to detect false assertions one> > is required to observe the programs internal state.> > That is what assertions do.>
Here we go again. To observe state /= to observe correctness.

(Here we go again.) To observe state = to observe incorrectness
if the programmer correctly uses DbC (I've already showed you
a few examples, so I don't know why you keep insisting at this
point).
State observation is a contracted behavior. Any program is just a FSM.

As a result of a program constructed and defined by
programmers.

A DbC programmer puts *redundant* assertions in the code
to detect incorrect states (beats me why this is so difficult
to understand by you).
And what a> FSM does? It observes its state and goes to another one.

So?

What is your point?

Are you saying that a FSM machine cannot be built
to protect itself from some nasty, non intended
behaviors?

(That's simply absurd.)
That assertions indeed observe states is the point Daniel, Oliver and I are> defending.

That they, doing precisely that, can detect incorrect states
has been my point (and DbC's approach).
They don't check correctness.

They can detect incorrect behaviors, hence they check the correctness
of different parts of programs. They just are unable to ensure total
program correctness.
Like hardware> >> interrupts do. Ada has software ATCs. Anyway, after an ATC any continuation> >> on the context caused ACT is impossible.> >
So the failed program behavior is synchronous after all.> > It stop immediately. Are ATC's an exception> > mechanism to outside concurrent entities?>
Technically it breaks at the first point where it can.

So, technically, it could be after launching the nuclear missile?
Exception are a similar internal thing. They stop normal> > program execution, passing the control to the separated> > exceptional world (we don't disagree that much in this> > regard).>
It only appears so. You can use anything you want for correctness checks,> if you can be sure that the program being checked does not influence one> that checks.

That's why *pre*conditions (and invariants) are so important
(and not expressible as postconditions). Any runtime
checked precondition *precedes* nasty behaviors.
Exceptions as they are implemented in all languages I know,> are unsuitable for this.

They are not, if exceptions are throwned *before* the
program begins an erratic behavior.
ATCs, system traps, calls to supervisor are much> better. Physically separated systems are even more better.

We agree in this last point.

I just don't see what that was to do with the runtime use
of DbC inside programs, and why runtime preconditions
are not tested preconditions.
Basically it is an abort, this the> >> only way real preconditions might be checked at run-time - by an> >> *independent* system.> >
I've already showed you that is not true (you take a very> > extreme outside view of programs, as if programs could> > not know nothing of themselves!).>
No. I only claim that a program cannot know anything about its correctness.

(Really?)

So a module, that is expected -for example- to solve in R a second
degree equation, cannot ever know if the values of "a", "b" and
"c" have real roots. I would say that a simple (run time) calculation
of the sign of (b^2-4ac) was more than enough.

So, in my book, if another part of the program is attempting to
use that module expecting that such a solution exists, it is
making a program error. You apparently don't think the
same way (or you are simply playing with words).

On the other hand, if you are claiming that a program *by itself*
lacks intelligence to be aware, for example, of its own existence
or its correctness. That's obvious (and quite beside the point).
The *programmer* knows what are the expected correct
behaviors and enforces them by the use of contracts. Run time
verifiable contracts, when broken, ensure the programmer
that the program is incorrect, and so he can chose to build
its programs to respond to such errors, or simply to let
the program die gracefully.
About itself, a program knows its state.

Exactly. That is more than enough for runtime
assertions to detect some incorrect programs.
So I was using a "reductio ad absurdum"> >>> argument, in which I attempted to show> >>> that exceptional behavior (being goto like)> >>> is outside normal structured (single entry> >>> and exit points) view of programs.> >>
Sort of.> >
Either it is, or it isn't!>
The definition of structured programming isn't that formal.

I'm using Dijkstra's approach ("Structured Programming",
page 19, 1972, Academic Press). Do you have a better suggestion?

(Yes, I'm also know Knuth's articles on the subject.)
You cannot> point at a program and say whether it is well structured or not. There are> cases where gotos are better structured than if-then-else.>
Still exceptional behavior is a behavior. Program error is not.> >
Exceptional behavior is the behavior a incorrect program> > should take.>
[ Don't you see any problems with such statements? ]

No.
A correct behavior of an incorrect program?

Exactly.
Would an incorrect program> become correct by raising an exception?

No (obviously).

(Where did I said that?)

Read more carefully, and stop playing with words.
The appropriate (->correct) behavior a program
should take as a response to detected incorrect
state, is to raise an exception. If, resulting from
that exception, the program is able to recover
-correcting itself by the use of redundant
code- or not (case in which it should terminate
its execution), is a problem up to the
programmer.
Was it incorrect before it raised> the exception?

If the exception was a result of a false assertion, yes.
But it is definitely correct after doing that! Ah, maybe, it> was always correct except for a negligible period of time required to raise> an exception? Wouldn't be any program correct if we implemented it as:>
procedure Foo is> begin> raise Oh_My_God;> end Foo;

I'll take all these last absurd comments as a (funny)
joke on your part.

Take a little time to understand the other "side"'s
arguments, before writing fallacious absurd things.
Then, either the program is unable to cope> > with the failure and exceptions are propagated until> > the final abortion of the program (nothing stops> > another program to take its place as you suggest);>
Isn't is so, that any program is correct as long as it keeps on coping> with?

A program is correct if all its runnable and intended
contracts are always observed.
--> Regards,> Dmitry A. Kazakov> http://www.dmitry-k­azakov.de

-miguel

--
Miguel Oliveira e Silva

Add comment
S Perryman 6 March 2006 14:28:27 permanent link ]
 "Oliver Wong" <owong@castortech.c­om> wrote in message
news:CX_Nf.8680$Ui.­8021@edtnps84...
<ggroups@bigfoot.co­m> wrote in message > news:1141384594.168­474.257720@z34g2000c­wc.googlegroups.com.­..
Oliver Wong wrote:
[ Design By Contract saga snipped, but acknowledged ]
It's bad for the supplier because he cannot get any clients to use it.>>> What's the point of creating a method if it will never be used? It's >>> wasted effort on the supplier's part.
But I guess it's useless to proceed further with this until we define>>> metrics for "good" and "bad" for the supplier and client.
It is GOOD for the client if he can find an implementation of a contract>>> which solves his problem without imposing too many pre-conditions.
It is GOOD for the supplier if he can find a client who will agree to a>>> contract with the supplier.
The best components from the users' viewpoint are those that have the>> weakest preconditions and strongest post/invariant conditions.
The suppliers' viewpoint is the converse.
Within those extremes we have a dynamic where components arrive at>> contracts that are amenable to both (usage, implementation effort etc) .
Hence the term *contract* . Contracts are negotiated are they not ...
The problem with this is that if it were true that it's best for the > supplier to implement components with the strongest pre-conditions and the > weakest post-conditions, then no one would ever implement any component > except for this one:
/*> pre-condition: false.> post-condition: does nothing> */> void doesNothing() {> }
But why isn't that what we observe in real life?

Because the component *does nothing* .
Therefore it is of no use. It is not real life, regardless of its contract.

<quote>
The art is to find the weakest possible [precondition] and the strongest
possible
[postcondition] that characterize your intent as to what the module is
supposed
to do.
</quote>

The quote captures the essence of the problem.

Because there's an ADDED factor that a supplier will not want to waste > his/her time implementing a component that no one wants to use! That's the > point I was trying to make.

But you have not made that point at all IMHO.
A supplier generally builds components that is intended for some use.

What determines whether a potential user will use that component ??

a) preconditions too strong (usage too constrained)
b) postconditions too weak (no observable measures of correctness)

Component contracts evolve through usage and horse-trading.
Not in a vacuum.


Regards,
Steven Perryman


Add comment
S Perryman 6 March 2006 14:33:46 permanent link ]
 "Dmitry A. Kazakov" <mailbox@dmitry-kaz­akov.de> wrote in message
news:5966u7leuxqk$.­nuv7gvvewc93.dlg@40t­ude.net...
On 3 Mar 2006 03:16:34 -0800, ggroups@bigfoot.com­ wrote:
The best components from the users' viewpoint are those that have the>> weakest preconditions and strongest post/invariant conditions.
The suppliers' viewpoint is the converse.
Within those extremes we have a dynamic where components arrive at>> contracts that are amenable to both (usage, implementation effort etc)
Hence the term *contract* . Contracts are negotiated are they not ...
Maybe, but there is also somebody who assigns suppliers and consumers,> responsible for the problem decomposition. Now the question is, when the> negotiation takes place. Before or after the roles have been identified?

Negotiation should be ongoing, based on the realities.
Which means before/during/after­ identification of such "roles" .


Regards,
Steven Perryman


Add comment
Oliver Wong 6 March 2006 18:40:05 permanent link ]
 
"Kenneth P. Turvey" <kt-usenet@squeakyd­olphin.com> wrote in message
news:p­an.2006.03.05­.00.23.32.448064@squ­eakydolphin.com...> On Fri, 03 Mar 2006 18:32:06 +0000, Oliver Wong wrote:>
If the client will never set s = null, the nthe client can use either >> B>> or A, as they will both perform identically for all situations the client>> will encounter.>
I should note that this isn't strictly true. Client B must do some work> to check to see if the constraint is violated. This may be a small amount> of work or a large amount of work, but it will take time. Client A will> get the same answer on every case in which it is defined and will perform> better than client B.

I'm not sure I understand what you're saying. Which constraint are you
referring to when you say "client B must [...] check to see if *THE*
constraint is violated" (emphasis added)?

AFAICT, the set of all cases which contract A defines is a subset of the
set of all cases which contract B defines. If a client is willing to accept
contract A, then that client is only interested in those cases, and should
thus receive similar performance with both implementations A and B.

- Oliver

Add comment
Miguel Oliveira e Silva 6 March 2006 19:20:27 permanent link ]
 Oliver Wong wrote:
"Kenneth P. Turvey" <kt-usenet@squeakyd­olphin.com> wrote in message> news:p­an.2006.03.05­.00.23.32.448064@squ­eakydolphin.com...> > On Fri, 03 Mar 2006 18:32:06 +0000, Oliver Wong wrote:> >
If the client will never set s = null, the nthe client can use either> >> B> >> or A, as they will both perform identically for all situations the client> >> will encounter.> >
I should note that this isn't strictly true. Client B must do some work> > to check to see if the constraint is violated. This may be a small amount> > of work or a large amount of work, but it will take time. Client A will> > get the same answer on every case in which it is defined and will perform> > better than client B.>
I'm not sure I understand what you're saying. Which constraint are you> referring to when you say "client B must [...] check to see if *THE*> constraint is violated" (emphasis added)?

Because the exceptional behavior is part of its postcondition
(instead of being part of the precondition). Hence the routine
is obligated to *always* implement that (defensive) behavior
(since the precondition is true, he cannot assume that
sane clients will not use the routine simple to raise an
exception).
AFAICT, the set of all cases which contract A defines is a subset of the> set of all cases which contract B defines. If a client is willing to accept> contract A, then that client is only interested in those cases, and should> thus receive similar performance with both implementations A and B.

If, in contract A, the runtime checking of the (runnable) precondition
is enable, yes: both performances can be similar. However, in A,
the programmer may disable the precondition runtime check.
In those cases, the routine will perform better (no redundant
defensive check in the routine's implementation).

The decision to disable runtime assertions is up to the
programmer. He knows that in DbC assertions are
redundant tests in *correct* programs. So if he feels
confident that all uses of contract A are correct,
he can safely disable them.
- Oliver

-miguel

--
Miguel Oliveira e Silva


Add comment
Oliver Wong 6 March 2006 19:42:09 permanent link ]
 
"Miguel Oliveira e Silva" <mos@det.ua.pt> wrote in message
news:440C614B.D7963­519@det.ua.pt...> Oliver Wong wrote:>
"Kenneth P. Turvey" <kt-usenet@squeakyd­olphin.com> wrote in message>> news:p­an.2006.03.05­.00.23.32.448064@squ­eakydolphin.com...>>­ > On Fri, 03 Mar 2006 18:32:06 +0000, Oliver Wong wrote:>> >
If the client will never set s = null, the nthe client can use >> >> either>> >> B>> >> or A, as they will both perform identically for all situations the >> >> client>> >> will encounter.>> >
I should note that this isn't strictly true. Client B must do some >> > work>> > to check to see if the constraint is violated. This may be a small >> > amount>> > of work or a large amount of work, but it will take time. Client A >> > will>> > get the same answer on every case in which it is defined and will >> > perform>> > better than client B.>>
I'm not sure I understand what you're saying. Which constraint are >> you>> referring to when you say "client B must [...] check to see if *THE*>> constraint is violated" (emphasis added)?>
Because the exceptional behavior is part of its postcondition> (instead of being part of the precondition). Hence the routine> is obligated to *always* implement that (defensive) behavior> (since the precondition is true, he cannot assume that> sane clients will not use the routine simple to raise an> exception).

Yes, but my question was what constraint is being tested?
AFAICT, the set of all cases which contract A defines is a subset of >> the>> set of all cases which contract B defines. If a client is willing to >> accept>> contract A, then that client is only interested in those cases, and >> should>> thus receive similar performance with both implementations A and B.>
If, in contract A, the runtime checking of the (runnable) precondition> is enable, yes: both performances can be similar. However, in A,> the programmer may disable the precondition runtime check.> In those cases, the routine will perform better (no redundant> defensive check in the routine's implementation).>
The decision to disable runtime assertions is up to the> programmer. He knows that in DbC assertions are> redundant tests in *correct* programs. So if he feels> confident that all uses of contract A are correct,> he can safely disable them.

Indeed, method A does slightly less than method B, so method A may be
slightly faster. In this example, it's faster by a single if-statement. I
don't dispute that (note that I phrased it as "Similar performance", not
"exactly the same").

Kenneth seem to be implying that there may be some "expensive"
constraint testing involved with B. By expensive, I assumed he meant
something like a different class of asymptotic performance (e.g. turning an
O(1) algorithm into an O(n) one, or something like that). That's why I was
asking which constraint is it that's being tested.

- Oliver

Add comment
Oliver Wong 6 March 2006 20:11:02 permanent link ]
 
"Daniel T." <postmaster@earthli­nk.net> wrote in message
news:p­ostmaster-982­AB6.19083303032006@n­ews.east.earthlink.n­et...> In article <16nNf.9996$dg.1352­@clgrps13>,> "Oliver Wong" <owong@castortech.c­om> wrote:>
I believe Daniel is taking the position that if "preconditions" are>> runnable, then they are part of the well defined behaviour of the >> program,>> and thus are part of the post-condition contract. It's not something I >> agree>> with though.>
Close, I'm taking the position that if "preconditions" are runnable AND> they are part of the well defined behavior of the function (as these so> called "runnable preconditions" in Eiffel, then they are part of the> post-condition contract. If you explicitly define what happens if value> == 0, then that is what *must* happen, it is no longer undefined.

From what I understand (I've never worked with Eiffel), you can turn off
the checking of require-clauses in Eiffel, sort of like you can turn on or
off the "assert" statements in Java. As such, I wouldn't say that it's
perfectly defined, just from the source code, what an Eiffel program does if
it's require-clauses are non-empty.

MAYBE those require-clauses will execute, or maybe they won't. This is
why I propose it's useful (in Eiffel at least) to distinguish between
runnable pre-conditions and post-conditions.

- Oliver

Add comment
Miguel Oliveira e Silva 6 March 2006 22:49:16 permanent link ]
 Oliver Wong wrote:
"Miguel Oliveira e Silva" <mos@det.ua.pt> wrote in message> news:440C614B.D7963­519@det.ua.pt...> > Oliver Wong wrote:> >
"Kenneth P. Turvey" <kt-usenet@squeakyd­olphin.com> wrote in message> >> news:p­an.2006.03.05­.00.23.32.448064@squ­eakydolphin.com...> >> > On Fri, 03 Mar 2006 18:32:06 +0000, Oliver Wong wrote:> >> >
If the client will never set s = null, the nthe client can use> >> >> either> >> >> B> >> >> or A, as they will both perform identically for all situations the> >> >> client> >> >> will encounter.> >> >
I should note that this isn't strictly true. Client B must do some> >> > work> >> > to check to see if the constraint is violated. This may be a small> >> > amount> >> > of work or a large amount of work, but it will take time. Client A> >> > will> >> > get the same answer on every case in which it is defined and will> >> > perform> >> > better than client B.> >>
I'm not sure I understand what you're saying. Which constraint are> >> you> >> referring to when you say "client B must [...] check to see if *THE*> >> constraint is violated" (emphasis added)?> >
Because the exceptional behavior is part of its postcondition> > (instead of being part of the precondition). Hence the routine> > is obligated to *always* implement that (defensive) behavior> > (since the precondition is true, he cannot assume that> > sane clients will not use the routine simple to raise an> > exception).>
Yes, but my question was what constraint is being tested?

I think it was the (s == NULL) test which selects the
exception throw instruction in the routine's
implementation.
AFAICT, the set of all cases which contract A defines is a subset of> >> the> >> set of all cases which contract B defines. If a client is willing to> >> accept> >> contract A, then that client is only interested in those cases, and> >> should> >> thus receive similar performance with both implementations A and B.> >
If, in contract A, the runtime checking of the (runnable) precondition> > is enable, yes: both performances can be similar. However, in A,> > the programmer may disable the precondition runtime check.> > In those cases, the routine will perform better (no redundant> > defensive check in the routine's implementation).> >
The decision to disable runtime assertions is up to the> > programmer. He knows that in DbC assertions are> > redundant tests in *correct* programs. So if he feels> > confident that all uses of contract A are correct,> > he can safely disable them.>
Indeed, method A does slightly less than method B, so method A may be> slightly faster. In this example, it's faster by a single if-statement. I> don't dispute that (note that I phrased it as "Similar performance", not> "exactly the same").

Ok. We agree then.
Kenneth seem to be implying that there may be some "expensive"> constraint testing involved with B. By expensive, I assumed he meant> something like a different class of asymptotic performance (e.g. turning an> O(1) algorithm into an O(n) one, or something like that).

I'm quite sure Kenneth was referring to what I said
(but, of course, only he can confirm that).

Anyway not all assertions are as simple, and efficient,
as testing null references. Many of them can involve
quite a long processing time (for example: to search
for an existing element in a container).
So, yes. It can make a huge difference
to run programs with assertions enabled
and disabled (the gnu SmartEiffel compiler
is one such cases). DbC is also excellent
to create efficient programs.
That's why I was> asking which constraint is it that's being tested.>
- Oliver

-miguel

--
Miguel Oliveira e Silva

Add comment
Oliver Wong 6 March 2006 23:27:16 permanent link ]
 
"Miguel Oliveira e Silva" <mos@det.ua.pt> wrote in message
news:440C923C.BC513­785@det.ua.pt...> Oliver Wong wrote:>
"Miguel Oliveira e Silva" <mos@det.ua.pt> wrote in message>> news:440C614B.D7963­519@det.ua.pt...>> > Oliver Wong wrote:>> >
"Kenneth P. Turvey" <kt-usenet@squeakyd­olphin.com> wrote in message>> >> news:p­an.2006.03.05­.00.23.32.448064@squ­eakydolphin.com...>>­ >> > On Fri, 03 Mar 2006 18:32:06 +0000, Oliver Wong wrote:>> >> >
If the client will never set s = null, the nthe client can use>> >> >> either>> >> >> B>> >> >> or A, as they will both perform identically for all situations the>> >> >> client>> >> >> will encounter.>> >> >

[snip]
Anyway not all assertions are as simple, and efficient,> as testing null references. Many of them can involve> quite a long processing time (for example: to search> for an existing element in a container).> So, yes. It can make a huge difference> to run programs with assertions enabled> and disabled (the gnu SmartEiffel compiler> is one such cases). DbC is also excellent> to create efficient programs.>

Okay, I see my mistake now, and my statement above is incorrect, because
it is too strong. So let me fall back on my previous claim (rephrased more
carefully):

For any contract "A" with runnable pre-conditions, if there exists a
client C who accepts contract A and uses an implementation of that contract
in their program, then it is always possible to construct a contract B such
that it has fewer (possibly zero) pre-conditions than contract A did, and
whose implementation can swapped in for the implementation of contract A
without changing the behaviour of the program (where behaviour includes
asymptotic runtime).

- Oliver

Add comment
Miguel Oliveira e Silva 7 March 2006 00:14:59 permanent link ]
 Oliver Wong wrote:
"Miguel Oliveira e Silva" <mos@det.ua.pt> wrote in message> news:440C923C.BC513­785@det.ua.pt...> > Oliver Wong wrote:> >
"Miguel Oliveira e Silva" <mos@det.ua.pt> wrote in message> >> news:440C614B.D7963­519@det.ua.pt...> >> > Oliver Wong wrote:> >> >
"Kenneth P. Turvey" <kt-usenet@squeakyd­olphin.com> wrote in message> >> >> news:p­an.2006.03.05­.00.23.32.448064@squ­eakydolphin.com...> >> >> > On Fri, 03 Mar 2006 18:32:06 +0000, Oliver Wong wrote:> >> >> >
If the client will never set s = null, the nthe client can use> >> >> >> either> >> >> >> B> >> >> >> or A, as they will both perform identically for all situations the> >> >> >> client> >> >> >> will encounter.> >> >> >
[snip]>
Anyway not all assertions are as simple, and efficient,> > as testing null references. Many of them can involve> > quite a long processing time (for example: to search> > for an existing element in a container).> > So, yes. It can make a huge difference> > to run programs with assertions enabled> > and disabled (the gnu SmartEiffel compiler> > is one such cases). DbC is also excellent> > to create efficient programs.> >
Okay, I see my mistake now, and my statement above is incorrect, because> it is too strong. So let me fall back on my previous claim (rephrased more> carefully):>
For any contract "A" with runnable pre-conditions, if there exists a> client C who accepts contract A and uses an implementation of that contract> in their program, then it is always possible to construct a contract B such> that it has fewer (possibly zero) pre-conditions than contract A did, and> whose implementation can swapped in for the implementation of contract A> without changing the behaviour of the program (where behaviour includes> asymptotic runtime).

Agreed.

Such a program is not, however, using a DbC approach
(it is a defensive approach).

I'm quite sure DbC approach (when applied to internal
contracts) is much (much) better in every respect.
Of course I'm willing to continue to argue about that.
- Oliver

Best regards,

-miguel

--
Miguel Oliveira e Silva

Add comment
Oliver Wong 7 March 2006 00:51:53 permanent link ]
 
"Miguel Oliveira e Silva" <mos@det.ua.pt> wrote in message
news:440CA653.61F0D­4D4@det.ua.pt...> I'm quite sure DbC approach (when applied to internal> contracts) is much (much) better in every respect.
[to defensive programming]> Of course I'm willing to continue to argue about that.

Well, before we get into an argument about this, I'd better understand
what I'm arguing about. ;)

What do you mean by "internal contracts"? I.e. what change in meaning
does the adjective "internal" cause when applied to "contracts" in this
context?

- Oliver

Add comment
Dmitry A. Kazakov 7 March 2006 13:32:12 permanent link ]
 On Mon, 06 Mar 2006 21:09:17 +0000, Miguel Oliveira e Silva wrote:
"Dmitry A. Kazakov" wrote:>
On Sun, 05 Mar 2006 19:04:39 +0000, Miguel Oliveira e Silva wrote:>>
"Dmitry A. Kazakov" wrote:>>>
On Sat, 04 Mar 2006 17:17:10 +0000, Miguel Oliveira e Silva wrote:>>>>
A flat tyre in my car does not affect its engine!>>
It does, but no matter.>
So if I change the tyre, I won't be sure the engine is still> working?

There are pressure sensors and all that stuff.
(Assuming, of course, that it was working before.)>
You live in a very strange complex world.

Never buy a new car, it might appear steer-by-wire! (:­-))
Any given part of a program is a program and any given part cannot check>> the correctness of itself.>
Assertions are redundant tests that apply to valid program states> to detect incorrect behaviors. The programmer chooses to> put those extra tests to assert its runtime correctness.> As I said many times, assertions are not part of the> routine implementation. They are at a different level> (the module interface in the case of preconditions,> postconditions and invariants).>
So your statement is wrong. The program is not testing> its own correctness as a whole (including the correctness> of assertions). Assertions are testing the program under> them. (Remember my persistent argument about separated> worlds? Assertions test the correctness of the normal> program.)

If the assertions aren't a part of the program, then the program does not
check the correctness of itself [by means of these assertions.] Neither
these assertions check the correctness of their own. Also, my statement
stands.

It isn't about where assertions belong to. You are free to choose them
being either out or in. Depending on the choice they either will be capable
to check the correctness or not. Your argumentation is based on a simple
trick. First you present one program, then after making some distracting
passes, you substitute the program with another and claim that it is same
and its correctnes is checked. No, it isn't.
And that brain (at least a wise one), in DbC, has putted inside> the same running program, two "programs". One, that I've been> calling normal, which is expected to do what ever is required.> And another, using runnable assertions, in which the former> program is tested.

That's just fine. This is the starting point of your opponents. Once we
have agreed on this, we can proceed to the next question. If the assertion
evaluation program "A" detects that the acting program "B" is incorrect,
what would be the proper behavior and what the word "behavior" addresses
here. Our point is that it is meaningless to talk about the behavior of B
at this stage. B has failed, it proved to be wrong. So exception
propagation in B would be nonsence. Now it is the behavior of A. It is A's
responsibility to do something about B. [ BTW, this is how all
fault-tolerant systems are built. ]
(As you can see, exceptions are not required for>>> normal behavior)>>
Turing completeness...>
Sorry, but I don't understand your point here.

It is an argumentation to Turing completeness. It is true that I can
program anything [Turing-complete] without exceptions (no pun (:­-)), as
well as without assertions and without lots of other stuff, people are
counting for useful.
If he insists that an integer must be read,> he should take the consequences when> the file/user does not give it that.

Of course it should. That is the postcondition of Read: you either have
read it or have not. It is not that you have read it or else the program is
wrong.
I would say that reading characters was more than enough> (and in fact is what I do in my handmade parsers.)>
After the characters have been read, all remaining> processing is within program's *internal* (strong)> contracts.

Huh, there is practically no real language for which legality of the source
code can be decided for any given program. So the approach you have
outlined is wrong, or at least impracticable. Examples vary from endless
C++'s /*...*/ comments and source lines to folding constant expressions
like 20**9999999/20**999­9999 etc. Exceptions are very handy for breaking
potentially infinite recursion.
Upon exception propagation local objects>> are finalized.>
In the failed precondition object, there are> no local objects (because the routine did> not started its execution).

That is not the context where incorrectness was detected. It is also not
the context where exception propagates. But you have conceded it in the
next paragraph.
If the program is incorrect, these finalizations *cannot* be>> performed, because their preconditions might be false.>
The programmer is free to allow exception propagation> to where he wants to. He cannot trust objects which> where interrupted during one of their service executions.

So he must foresee how exceptions will propagate and handle the
corresponding side effects. That's the whole point. He can't do it if the
program is in a non-state. Continuation is only then possible, when the
state is known. [It is a FSM, after all.] If the state is known, then it is
a correct state.
If you are able to know the reason why the program is incorrect> (assertions), there is lots of safe things that we can do.

Assertions don't tell "why." Deduction process is on the programmer's part.
My position is very simple - if you check something then you should well
know what you will do for any possible outcome. Otherwise, it is
irresponsible.
So in your opinion a new big-bang is *always* required.>>>
(If I've used that strategy to my sixteen year old car,>>> I would have bought quite a few hundreds of>>> cars by now.)>>
I'm dying to know how your car would drive without wheels.>
You (again) didn't get the point.

It was your example. You seemed to claim that when something is incorrect,
no matter what, one can still rely on the car's behavior...
When one program is incorrect that might (but need not to) be a state of>> another program. If anybody feels sorrow about it, then not the incorrect>> program.>
(You're a little bit lost in there.)>
Yet-another-example­:>
If I replace "sqr" function with> a DbC one:>
double sqr(double x)> {> double result;>
result = 2*x;>
assert(result == x*x); // postcondition> return result;> }>
I'll get an *incorrect* program> in which its states are *able*,> *sometimes*, to detect its> incorrectness.

That's funny, it will fail even if result would have been correctly
evaluated. Real sqrt isn't specified this way. But anyway, read my question
above and answer the following: in which state sqrt is, when assert returns
false. After doing that, proceed to:

double sqrt (double x)
{
double result;

result = <some iterative procedure to get square root>;

assert (result == 2*x); // postcondition

return result;
}
And anything it was, is the behavior.>
A program, unless if proved statically to be correct,> cannot protect itself from *all possible* incorrect> behaviors. It can, however, protect itself from incorrect> behaviors expressed as runnable assertions (that,> my friend, *is* DbC at work).

Huh, any behavior you can protect from, is not a behavior! Do non-existing
things exist?
The word "inside" is the only reason.>
Is it?

Yes, otherwise, you'd inevitably fall into a contradiction.
So a module, that is expected -for example- to solve in R a second>>> degree equation, cannot ever know if the values of "a", "b" and>>> "c" have real roots. I would say that a simple (run time) calculation>>> of the sign of (b^2-4ac) was more than enough.>>
This is not a correctness check.>
Yes it is.>
If you add it to the program, you also add>> two new states:>>
1. Here is R and check was OK>> 2. Here is R and check failed>
Of course (wasn't that what I was referring to?).

No. You have added two states. It is another program. Its correctness need
to be stated.
Now you have to say what your program will do in the second case.>
An exception was throwned (clients can handle it if they> have enough context information to correct the> detected error.)

So the contract is: either all right or exception. Which makes the program
correct when evaluation wasn't correct. Evaluation /= the whole program,
which now consists of evaluation and a check. When you add checks, you
become questions about false positives and false negatives, which then
determine the correctness of the [new] program.
Write a style checker. Take a large>> source code base and run your checker through. Then take a sample of>> experienced programmer and let them maintain this code 1-2 years. Then>> compare what your checker said, what did say the programmers, and what were>> the maintenance costs. The rest is statistics.>
What is your point?

That "well-structured" program is not a well defined term. People disagree
on this issue.

--
Regards,
Dmitry A. Kazakov
http://www.dmitry-k­azakov.de
Add comment
Miguel Oliveira e Silva 7 March 2006 14:21:34 permanent link ]
 Oliver Wong wrote:
"Miguel Oliveira e Silva" <mos@det.ua.pt> wrote in message> news:440CA653.61F0D­4D4@det.ua.pt...> > I'm quite sure DbC approach (when applied to internal> > contracts) is much (much) better in every respect.> [to defensive programming]> > Of course I'm willing to continue to argue about that.>
Well, before we get into an argument about this, I'd better understand> what I'm arguing about. ;)

Wise decision.
What do you mean by "internal contracts"?

(I have already provided a definition.)

Internal contracts are the ones a program can
take responsibility to ensure 100% (not
99.99...99%, but 100%).

The reason I have make such a thing explicit,
was to try to reduce our communication problems.
Many times a program cannot take 100%
responsibility for a given behavior, because
such behavior depends on external entities
(file handling, user input, embedded systems, etc.).
In those cases, a defensive approach (which may
include exceptions) is a wise decision.

Initially, I *wrongly* gave the idea (it was
not intended) that exceptions are only to
express defined behavior for incorrect
programs (with false assertions). So a
lot of noise resulted from there (despite
my attempts to make things crystal clear).
My original claim was (and is) that
exceptions are the required behavior
for a detected incorrect program.
I.e. what change in meaning> does the adjective "internal" cause when applied to "contracts" in this> context?

Its meaning is now clear to you?
- Oliver

Best regards,

-miguel

--
Miguel Oliveira e Silva

Add comment
Miguel Oliveira e Silva 7 March 2006 16:47:21 permanent link ]
 Dmitry,

It is very difficult (and unproductive) to argue
against a "moving target".

Please take the time (or not) to read my messages
from the start, and surely you'll see that I don't use
rhetorical "tricks" to present my arguments and
to support what DbC is. I tooked extreme care to
precisely define the terms I use (definitions that
you chosed to ignore at your convenience, arguing
back with fallacious absurd comments, or even with
my own arguments), and to match those definitions
with DbC terminology.
That was the case of normal and exceptional
behavior in the context of DbC (which I have
defined since the very beginning).

In fact you should not read my messages, you
should *learn* what DbC is from those original
established references (feel free to ask for them).

We can, of course, discuss if DbC (the real
one, given by established references) is good
or bad when compared with *other* approaches.
(In fact I've been doing that from the start
comparing it with defensive approaches.).
At this moment, I just feel that it is useless
to persist a deft conversation with someone
which (deliberately or not) refuses to
understand what I'm saying (replying back
with my own arguments as if they were not,
is quite an amusing *trick* to someone
as myself, used to many lengthy argumentations
in environmental policy, and politics, wars
here in Portugal), and persists with ambiguous
confusing messages.

I also provided references for the other
established terms I use, such as structured
programming. Again your only response to
that, instead of acknowledging the correctness
(or not) of those references (is it that difficult
for you to concede and explicitly agree with
other people?), was to keep on saying that
there are (somewhere) people who disagree
with such definitions (as if I didn't know
that). Communication, exactly as with
contracts, requires two sides willing to
communicate (willing to teach *and*
learn).

Select precisely the points you want to discuss
(I quite sure that most of them were already
approached), making *your* definitions very
clear, so that we can indeed communicate
productively with each other.

Best regards,

-miguel


"Dmitry A. Kazakov" wrote:> (...)
--> Regards,> Dmitry A. Kazakov> http://www.dmitry-k­azakov.de

--
Miguel Oliveira e Silva

Add comment
Oliver Wong 7 March 2006 18:57:23 permanent link ]
 
"Miguel Oliveira e Silva" <mos@det.ua.pt> wrote in message
news:440D6CBE.F233E­A0@det.ua.pt...> Oliver Wong wrote:>
"Miguel Oliveira e Silva" <mos@det.ua.pt> wrote in message>> news:440CA653.61F0D­4D4@det.ua.pt...>> > I'm quite sure DbC approach (when applied to internal>> > contracts) is much (much) better in every respect.>> [to defensive programming]>> > Of course I'm willing to continue to argue about that.>>
Well, before we get into an argument about this, I'd better >> understand>> what I'm arguing about. ;)>
Wise decision.>
What do you mean by "internal contracts"?>
(I have already provided a definition.)>
Internal contracts are the ones a program can> take responsibility to ensure 100% (not> 99.99...99%, but 100%).>
The reason I have make such a thing explicit,> was to try to reduce our communication problems.> Many times a program cannot take 100%> responsibility for a given behavior, because> such behavior depends on external entities> (file handling, user input, embedded systems, etc.).> In those cases, a defensive approach (which may> include exceptions) is a wise decision.>
Initially, I *wrongly* gave the idea (it was> not intended) that exceptions are only to> express defined behavior for incorrect> programs (with false assertions). So a> lot of noise resulted from there (despite> my attempts to make things crystal clear).> My original claim was (and is) that> exceptions are the required behavior> for a detected incorrect program.>
I.e. what change in meaning>> does the adjective "internal" cause when applied to "contracts" in this>> context?>
Its meaning is now clear to you?

Yes, and I don't dispute your claim, so no argument is nescessary, I
think. =)

- Oliver

Add comment
S Perryman 7 March 2006 20:34:47 permanent link ]
 "Oliver Wong" <owong@castortech.c­om> wrote in message
news:J2iPf.16201$vC­4.13731@clgrps12...
I guess if I had to only emphasize one point right now, it would be my > logical-consistency­ point. To address the point, you would simply need to > answer this one question (there should only be two choices):
Are pre-conditions ALWAYS tested, or can they be disabled?
(a) They are ALWAYS tested.> (b) Sometimes they can be disabled.

With DbC, preconditions can be enabled/disabled for a component, by the
component user. Which is possible because preconditions are adornments
of the component.

Contrast with defensive programming, where the equivalent conditions are
embedded within the component (how does one enable/disable the conditions
when you are given a pre-built component etc) .


Regards,
Steven Perryman


Add comment
Miguel Oliveira e Silva 8 March 2006 19:26:28 permanent link ]
 (My apologies for replying to myself.)

I wrote:
(...)
Oliver Wong wrote:>
(...)>
There's this one:> > http://groups.googl­e.ca/group/comp.soft­ware.testing/msg/ad3­6aefccffb8c47 but> > that's not the one I was thinking of.> >
I'm not saying having preconditions in your contract has the same> > >> ethical values of murdering nuns. I'm saying that if you want robust> > >> software, you should have fewer pre-conditions.> > >
Wrong.> > >
If you want robust programs, you should make sure they respect> > > their internal contracts (regardless of the strength of preconditions> > > and other assertions).> >
As I've said over and over again, if a module doesn't respect its> > contract, then you've got big problems.>
That's the easier part to ensure contracts: postconditions and> invariants depend only on the module implementation (it> is a local problem).

(I keep forgetting that there are some very important
things ensured in languages such as Eiffel, but that
cannot be taken for granted in other languages such
as C++ and Java. Sorry.)

To be more precise. A class invariant can only be a
local module problem if, and only if, there are no
public modifiable attributes. This kind of attributes
can, by definition, be unconditionally modified
directly by external clients, hence the module
is helpless to ensure their part on the invariant.

(Public modifiable attributes are a very [very]
bad idea.)
(...)

-miguel

--
Miguel Oliveira e Silva

Add comment
Chris Dollin 8 March 2006 19:51:55 permanent link ]
 Miguel Oliveira e Silva wrote:
To be more precise. A class invariant can only be a> local module problem if, and only if, there are no> public modifiable attributes. This kind of attributes> can, by definition, be unconditionally modified> directly by external clients, hence the module> is helpless to ensure their part on the invariant.

Suppose the class invariant is `the current value of
V is the value last written to it`. Then modifying
V does not violate the invariant.

Sometimes an object is just a shell round a variable.
(Public modifiable attributes are a very [very]> bad idea.)

Often. But not always.

--
Chris "sparqling" Dollin
"Who do you serve, and who do you trust?"
Add comment
Kenneth P. Turvey 12 March 2006 12:43:36 permanent link ]
 -----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

On Mon, 06 Mar 2006 20:27:16 +0000, Oliver Wong wrote:
For any contract "A" with runnable pre-conditions, if there exists a > client C who accepts contract A and uses an implementation of that contract > in their program, then it is always possible to construct a contract B such > that it has fewer (possibly zero) pre-conditions than contract A did, and > whose implementation can swapped in for the implementation of contract A > without changing the behaviour of the program (where behaviour includes > asymptotic runtime).

I've been thinking about this a bit and I think your statement is still
too strong. For example I have a method that updates some sub-set in a
set:

void updateSubSet(SomePa­ram param) {
..
}

The preconditions include the pre-condition that no element of set will
be null and the post-conditions include the post-condition that no element
of set will be null.

The method must make sure that any updates it makes to the the set do not
result in null values. Since it can be confident that the set didn't
contain any null values when it was called, it was a precondition, it can
guarantee that the set will not have any null when it completes.

In order to replace this method with a method that does not have the
pre-condition requiring that all elements are defined in the set means
that the method must iterate over every element in the set and check it.
This is not asymptoticly the same as the original since the original only
had to look at the subset. We can imagine that the entire set is possibly
infinite.

- --
Kenneth P. Turvey <kt-usenet@squeakyd­olphin.com>
Phone : (314) 255-2199

XMPP IM: kpturvey@jabber.org­
Yahoo IM: kpturvey2
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.1 (GNU/Linux)

iD8DBQFEE98ri2ZgbrT­ULjoRAnCPAKCMmGHqKPV­CXsAmnq3NqRwHK47fKQC­fUOuL
DpsgBolfdB12uZbF0+z­Dx5A=
=CQf6
-----END PGP SIGNATURE-----

Add comment
Oliver Wong 13 March 2006 19:21:35 permanent link ]
 
"Kenneth P. Turvey" <kt-usenet@squeakyd­olphin.com> wrote in message
news:p­an.2006.03.12­.08.43.30.195267@squ­eakydolphin.com...>
On Mon, 06 Mar 2006 20:27:16 +0000, Oliver Wong wrote:>
For any contract "A" with runnable pre-conditions, if there exists a>> client C who accepts contract A and uses an implementation of that >> contract>> in their program, then it is always possible to construct a contract B >> such>> that it has fewer (possibly zero) pre-conditions than contract A did, and>> whose implementation can swapped in for the implementation of contract A>> without changing the behaviour of the program (where behaviour includes>> asymptotic runtime).>
I've been thinking about this a bit and I think your statement is still> too strong. For example I have a method that updates some sub-set in a> set:>
void updateSubSet(SomePa­ram param) {> ..> }>
The preconditions include the pre-condition that no element of set will> be null and the post-conditions include the post-condition that no element> of set will be null.>
The method must make sure that any updates it makes to the the set do not> result in null values. Since it can be confident that the set didn't> contain any null values when it was called, it was a precondition, it can> guarantee that the set will not have any null when it completes.>
In order to replace this method with a method that does not have the> pre-condition requiring that all elements are defined in the set means> that the method must iterate over every element in the set and check it.> This is not asymptoticly the same as the original since the original only> had to look at the subset. We can imagine that the entire set is possibly> infinite.

You would be correct if I had omitted the keyword "runnable" before
"pre-conditions", but since the pre-condition "no element of the set will be
null" is not runnable in the case where the set is infinite, then this
"counter example" doesn't actually counter my statement above.

I must admit I hadn't considered the example you proposed though, and it
does make me more nervous now about the truth value of my statement. ;)

- Oliver

Add comment
Kenneth P. Turvey 14 March 2006 01:35:37 permanent link ]
 -----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

On Mon, 13 Mar 2006 15:21:35 +0000, Oliver Wong wrote:
You would be correct if I had omitted the keyword "runnable" before > "pre-conditions", but since the pre-condition "no element of the set will be > null" is not runnable in the case where the set is infinite, then this > "counter example" doesn't actually counter my statement above.

Even with the "runnable" one can imagine that checking the entire set is
O(n^2) while just checking the subset is O(n). The point was that the
extra time a method takes after your transformation is unbounded by the
original runtime.
I must admit I hadn't considered the example you proposed though, and it > does make me more nervous now about the truth value of my statement. ;)

I think your statement is true until you start making claims about
runtime. As soon as you do, I think you are leaving out a large class of
possible pre-conditions. The example I just gave is an example of a "Good
Data in -> Good data out" set of conditions that isn't at all atypical and
often would require quite a bit of effort to convert to "Any data in ->
Good data out or exception".

- --
Kenneth P. Turvey <kt-usenet@squeakyd­olphin.com>

XMPP IM: kpturvey@jabber.org­
Yahoo IM: kpturvey2
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.1 (GNU/Linux)

iD8DBQFEFeWdi2ZgbrT­ULjoRAsZ1AJ9WbW3n2ES­KrvSb8zSuZYxoFS1sJwC­g12wa
JtvA9KrxCLz4Jghr3r3­Re74=
=FQvw
-----END PGP SIGNATURE-----

Add comment
Oliver Wong 14 March 2006 01:49:18 permanent link ]
 
"Kenneth P. Turvey" <kt-usenet@squeakyd­olphin.com> wrote in message
news:p­an.2006.03.13­.21.35.32.807446@squ­eakydolphin.com...> -----BEGIN PGP SIGNED MESSAGE-----> Hash: SHA1>
On Mon, 13 Mar 2006 15:21:35 +0000, Oliver Wong wrote:>
You would be correct if I had omitted the keyword "runnable" before>> "pre-conditions", but since the pre-condition "no element of the set will >> be>> null" is not runnable in the case where the set is infinite, then this>> "counter example" doesn't actually counter my statement above.>
Even with the "runnable" one can imagine that checking the entire set is> O(n^2) while just checking the subset is O(n). The point was that the> extra time a method takes after your transformation is unbounded by the> original runtime.

I'll try to make this discussion more concrete by providing pseudo code. So
contract A, and implementation A, look like this:

/*
pre: data does not contain null.
post: return some subset of data. This subset will not contain null.
*/
public implementationA(dat­a) {
return getEveryOtherElemen­tIn(data);
}

/*
pre: none.
post: returns some subset of data. If data did not contain null, the subset
will not contain null either.
*/
public implementationB(dat­a) {
return getEveryOtherElemen­tIn(data);
}
I must admit I hadn't considered the example you proposed though, and >> it>> does make me more nervous now about the truth value of my statement. ;)>
I think your statement is true until you start making claims about> runtime. As soon as you do, I think you are leaving out a large class of> possible pre-conditions. The example I just gave is an example of a "Good> Data in -> Good data out" set of conditions that isn't at all atypical and> often would require quite a bit of effort to convert to "Any data in ->> Good data out or exception".

You are probably correct about it being difficult to convert "Good Data
in -> Good Data out" to "Any data in -> Good data out or exception", but
perhaps it's "always easy" to convert it to "Good data in -> Good data out;
Bad data in -> Bad data out".

- Oliver

Add comment
 

Add new comment

As:
Login:  Password:  
 
 
  
 
Пожалуйста, относитесь к собеседникам уважительно, не используйте нецензурные слова, не злоупотребляйте заглавными буквами, не публикуйте рекламу и объявления о купле/продаже, а также материалы нарушающие сетевой этикет или законы РФ. Ваш ip-адрес записывается.


QAIX > Software, Computer Help > Unit Testing and Test Cases 7 March 2006 20:34:47

see also:
[bug] Admin User Creation Broken
RFC: Flexinode Flexibility Should Be…
Leaflet, my comments
pass tests:
Do you know women?
Trix
see also:
Free Download 1080p HD YouTube Videos…
How to Playback AVI Files on Mac for…
How to Burn iTunes Videos/Movies/TV…

  Copyright © 2001—2010 QAIX
Идея: Монашёв Михаил.
Авторами текстов, изображений и видео, размещённых на этой странице, являются пользователи сайта.
See Help and FAQ in the community support.qaix.com.
Write in the community about the bugs you have noticedbugs.qaix.com.
Write your offers and comments in the communities suggest.qaix.com.
Information for parents.
Пишите нам на .
If you would like to report an abuse of our service, such as a spam message, please .
Если Вы хотите пожаловаться на содержимое этой страницы, пожалуйста .