From: Dmitry A. Kazakov on
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-kazakov.de
From: Kenneth P. Turvey on
-----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(a)squeakydolphin.com>
Phone : (314) 255-2199

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

iD8DBQFECi87i2ZgbrTULjoRArijAJ43kBosnncZ5GaZg0M4TZBXB/3SUwCgnKgN
sGD5esbNw9JyP7/Xpo2rcj0=
=j2NN
-----END PGP SIGNATURE-----

From: Miguel Oliveira e Silva on
"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_successful: BOOLEAN

last_read_was_an_integer: BOOLEAN

last_integer: INTEGER is
require
last_read_successful;
last_read_was_an_integer

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.google.com/group/comp.object/tree/browse_frm/thread/b9462e645bc4798d/fcc473cb64842ae2?rnum=21&_done=%2Fgroup%2Fcomp.object%2Fbrowse_frm%2Fthread%2Fb9462e645bc4798d%2F76f50acc016b1fbb%3Ftvc%3D1%26#doc_269e3a59a5710360

) 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-kazakov.de

-miguel

--
Miguel Oliveira e Silva

From: S Perryman on
"Oliver Wong" <owong(a)castortech.com> wrote in message
news:CX_Nf.8680$Ui.8021(a)edtnps84...

> <ggroups(a)bigfoot.com> wrote in message
> news:1141384594.168474.257720(a)z34g2000cwc.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


From: S Perryman on
"Dmitry A. Kazakov" <mailbox(a)dmitry-kazakov.de> wrote in message
news:5966u7leuxqk$.nuv7gvvewc93.dlg(a)40tude.net...

> On 3 Mar 2006 03:16:34 -0800, ggroups(a)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


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