From: Daniel T. on
In article <4404E104.CA725428(a)det.ua.pt>,
Miguel Oliveira e Silva <mos(a)det.ua.pt> wrote:

> "Daniel T." wrote:
>
> > In article <4404AB97.37B38F68(a)det.ua.pt>,
> > Miguel Oliveira e Silva <mos(a)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-preconditions 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.
From: Daniel T. on
In article <7fyp5pt4hnq7.1jec4c7748d0u$.dlg(a)40tude.net>,
"Dmitry A. Kazakov" <mailbox(a)dmitry-kazakov.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.
From: Oliver Wong on
"Miguel Oliveira e Silva" <mos(a)det.ua.pt> wrote in message
news:4404D2B9.176463A5(a)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

From: Oliver Wong on

"Dmitry A. Kazakov" <mailbox(a)dmitry-kazakov.de> wrote in message
news:7fyp5pt4hnq7.1jec4c7748d0u$.dlg(a)40tude.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

From: Oliver Wong on

"Miguel Oliveira e Silva" <mos(a)det.ua.pt> wrote in message
news:4404ED6B.CFB9753E(a)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

First  |  Prev  |  Next  |  Last
Pages: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
Prev: Teaching OO
Next: multimethod + multiple inheritance