From: Daniel T. on
In article <f8qecv$37t$1(a)aioe.org>, "S Perryman" <a(a)a.net> wrote:
> "Daniel T." <daniel_t(a)earthlink.net> wrote:
>
> > In article <f8q0tl$q07$1(a)aioe.org>, "S Perryman" <a(a)a.net> wrote:
>
> DT> (2) Such preconditions often are a repeat of the invariant of the class.
>
> > > I have never seen a pre-condition that is a 'repeat' of an invariant.
> > > Feel free to give an example.
> >
> > class RANGE
> > feature
> > low : INTEGER
> > high : INTEGER
> >
> > setLow( value : INTEGER )
> > require value < high
> > ensure low = value
> > high = old high
> > end
> >
> > invariant
> > low < high
> > end
> >
> > My Eiffel is a bit rusty, but notice how "value < high" is basically the
> > same as "low < high" because "setLow" assures the equivalence between
> > "low" and "value"
>
> (value < SELF.high) is not the same condition as (SELF.low < SELF.high) .
>
> Both use a common operation ( < ) , and parameter (SELF.high) .
> But neither of the above makes one condition "repeat" the other (you need
> value = SELF.low in order to achieve that) .

Ah, but the ensure is "value = SELF.low" . That is what I am talking
about when I say that the precondition repeats the invariant. The
terminology may be week, but the code makes the point, I think.
From: S Perryman on
"Daniel T." <daniel_t(a)earthlink.net> wrote in message
news:daniel_t-E87AFE.15562201082007(a)news.west.earthlink.net...

> In article <f8qecv$37t$1(a)aioe.org>, "S Perryman" <a(a)a.net> wrote:

DT> class RANGE
DT> feature
DT> low : INTEGER
DT> high : INTEGER

DT> setLow( value : INTEGER )
DT> require value < high
DT> ensure low = value
DT> high = old high
DT> end

DT> invariant
DT> low < high
DT> end

DT> My Eiffel is a bit rusty, but notice how "value < high" is basically the
DT> same as "low < high" because "setLow" assures the equivalence between
DT> "low" and "value"

>> (value < SELF.high) is not the same condition as (SELF.low < SELF.high) .

>> Both use a common operation ( < ) , and parameter (SELF.high) .
>> But neither of the above makes one condition "repeat" the other (you need
>> value = SELF.low in order to achieve that) .

> Ah, but the ensure is "value = SELF.low" . That is what I am talking
> about when I say that the precondition repeats the invariant.

The "ensure" is the *post-condition* , not the pre-condition.
The post-condition definitely "repeats" a term found in the pre-condition :
the
*invariant* .


>The terminology may be week, but the code makes the point, I think.

I think not (for either the terms used or the point being claimed) .

All I can see is a common condition C(x,y) which captures the essence
of numeric ranges. No problem with that.

C is used accordingly to define the invariant/pre-conditions of the Range
type. The *parameters* given to each use of C depend on the context
(which operation etc) .

But as I stated, unless the *values* of the parameters given to C by the
pre/
invariant conditions are *the same* at the point of evaluating the pre-
condition, there is no "repetition" (ironically if this was the case, setLow
etc
are effectively no-ops) .

OTOH, factoring a common condition C and then using it with different
parameters at different places is not repetition, merely good practice.


Regards,
Steven Perryman


From: H. S. Lahman on
Responding to Carter...

> In Bertrand Meyers book "Object oriented Software Construction" 2nd Ed he
> says section $11.8....(Discussing class invariants)
>
> "The precondition of a routine may involve the _initial state_ and the
> arguments."
>
> (Emphasis mine)
>
> I would argue that is a mistake. Since if the precondition involves the
> state of the object, it implies the calling routine must know the state of
> the object.

I think you are reading too much in the Meyer quote. Note the 'may'. In
the OO paradigm knowledge (state variable attributes) and behavior are
separated and treated quite differently. Any state variable that is
accessible through a relationship path can be accessed by a method so
/all/ such state variables are potentially part of the method's input
alphabet as far as DbC is concerned. All Meyer is saying is that there
is an implicit relationship path (via 'this') to the object's own state
data.

Since knowledge is separate from behavior, changing the state values is
done separately from invoking behaviors. (When a method sets state
variable, it has to invoke a synchronous accessor.) So what Meyer is
saying is that if the object's own data is accessed, then there is a
precondition on its state that may have to be satisfied by invoking an
object synchronous knowledge accessor before the behavior method is
invoked. That would be true no matter who owned the data being accessed
by the method.

[Note that for concurrent and/or asynchronous processing this separation
is crucial for efficient management of data integrity at the method
level. One has to ensure that no one updates the relevant state
variables while the method is executing. That is <relatively> easy to do
if one can count on the fact that all state variables are accessed
synchronously through dedicated accessors (when combined with
peer-to-peer collaboration). That's because one can figure out
syntactically what state variables are being accessed and use that to
ensure proper blocking. Corollary: it doesn't matter who owns the state
data; one just has to ensure it is timely (DbC precondition) and isn't
being changed as the behavior executes.]


*************
There is nothing wrong with me that could
not be cured by a capful of Drano.

H. S. Lahman
hsl(a)pathfindermda.com
Pathfinder Solutions
http://www.pathfindermda.com
blog: http://pathfinderpeople.blogs.com/hslahman
"Model-Based Translation: The Next Step in Agile Development". Email
info(a)pathfindermda.com for your copy.
Pathfinder is hiring:
http://www.pathfindermda.com/about_us/careers_pos3.php.
(888)OOA-PATH



From: Miguel Oliveira e Silva on
John Carter wrote:

> In Bertrand Meyers book "Object oriented Software Construction" 2nd Ed he
> says section $11.8....(Discussing class invariants)
>
> "The precondition of a routine may involve the _initial state_ and the
> arguments."
>
> (Emphasis mine)
>
> I would argue that is a mistake.

No it is not.

> Since if the precondition involves the
> state of the object, it implies the calling routine must know the state of
> the object.

Of course (if that is what is required by the contract expressed by the
precondition).

> This tends to be a violation of the "tell, don't ask" formulation of the
> Law of Demeter.

> For example...
> // In the client code...
> if( a.isSomePredicate())
> a.doThis();
> else
> a.doThat();
> end
> // In the object code...
>
> void A::dothis()
> {
> assert_precondition( isSomePredicate());
> ....
> }
>
> instead of the better pattern of...
>
> // In client code...
> a.doTheRightThing();
>
> // In the object code...
>
> class A {
> private:
> void doThis();
> void doThat();
> bool isSomePredicate();
>
> public:
> void dotheRightThing() {
> if( a.isSomePredicate())
> a.doThis();
> else
> a.doThat();
> }
>
> };

Why better [all the times]?


Lets look at a more concrete example:

class STACK[T]

feature

push( v: T) is ... end;

pop: T is
require
not is_empty
do ... end;

is_empty: BOOLEAN is ... end:

end -- STACK[T]

(In this case) It is definitely the clients responsibility
to send the pop message to a non-empty
STACK object. This object has no way of
knowing what to do (other then, of course,
raise an exception) inside a pop operation
in an empty STACK.

> Consider a typical example...
>
> while( stream.notEmpty?()) {
> value = stream.getNext();
> // do stuff...
> }
>
> This tends is messy and tends to be prone to errors arise out of the
> predicate changing value between the notEmpty? call and the getNext()

That is a concurrency problem (not a precondition limitation/problem).

There are several approaches (within the Eiffel community) to
this problem. Take a look at CORDIE06's proceedings:
http://www.artist-embedded.org/artist/Proceedings.html

And also this (draft) article:
http://www.ieeta.pt/~mos/pubs/inter-object-reservation-2006-draft.pdf

> (...)

> Question 1 to the group:
>
> Can you think of a case where the precondition _must_ involve the state?

Yes (lots of them).

Preconditions are assertions that clients are required to ensure.
If a service only makes sense to be used in particular states of
the object (partial function), then such contract should be clearly
expressed in its precondition (as in the pop operation of a stack).

> Question 2 to the group:
>
> Can you think of a case where the code is improved by allowing
> the precondition to depend on the state?

Yes (whenever there is a partial function on the object's state
involved).

Object-oriented languages and techniques are an
imperative approach to programming. Explicit state
is a required (a better word would be: desired) part
of it.

> Thank you,

Best regards,

-miguel

--
Miguel Oliveira e Silva