Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

IS A and HAS A relationships

74 views
Skip to first unread message

Mats Helander

unread,
Nov 17, 2001, 11:43:49 AM11/17/01
to
I have a question on IS A and HAS A relationships:

If a class "A" HAS A (sorry for the caps, don't mean to yell, but I'm under
the impression that's how you write'em relationships, yes?) class B, and it
declares that it "Implements" class B and then it delegates all the calls to
"Implemented" members in class A to the members of its instance of B (well,
static members would forward to class B, but you get what I mean,
right?)...Then, sure there was more work for me to obtain all this, but for
a user of my object A - will there be any "real" difference to if class A
had an IS A relationship to class B? I'm gathering that that the work
described above is more or less what the compiler does for you automagically
when you declare an IS A relationship...?

Sort of "academic" question, so I can't give you better example of the
programming situation I'll need to know about (don't have one) - so, if the
answere is so big that you would need to know that to answere me, suffice it
to say instead that there are indeed substantial differences...But of
course, I'll be glad to try to formulate my question more clearly if it was
muddy!

/Thanks in advance, Mats Helander


Scott W. Ambler

unread,
Nov 18, 2001, 8:36:47 AM11/18/01
to
If all that A does is delegate messages to B then the only difference is a
slight performance improvement from using inheritance (IS A) because you're
now directly invoking the operations on B instead of going through the
wrapper operations of A.

However, you never actually see such an extreme "pure wrapper" use of
aggregation (HAS A) so as you point out the question is sort of academic.
The important differences of inheritance and aggregation, assuming proper
application of them, focus on maintainability of your code.

- Scott
"Mats Helander" <ma...@urbantalk.se> wrote in message
news:3bf6...@news.wineasy.se...

Leonardo Azpurua

unread,
Nov 18, 2001, 2:06:00 PM11/18/01
to

<brou...@yahoo.com> escribió en el mensaje
news:esnfvt8dbuunbftuv...@4ax.com...

> "Mats Helander" <ma...@urbantalk.se> wrote:
>
> >Then, sure there was more work for me to obtain all this, but for
> >a user of my object A - will there be any "real" difference to if class A
> >had an IS A relationship to class B? I'm gathering that that the work
> >described above is more or less what the compiler does for you
automagically
> >when you declare an IS A relationship...?
>
> Inheritance (is-a) is more tightly coupling than containment (has-a).
> Coupling isn't necessarily a bad thing. But it can be. Most coding
> guidelines suggest to prefer solutions that are as loosely coupled as
> possible. In some situations, more coupling is desired. Just depends on
> the individual situation.

I perceive the "is-a" relation like a sort of definitory property of the
class. If classB "is-a" classA, then it has to implement all of the public
interface of a classA (in order to fulfill the Liskov Principle).

The has-a, on the other hand, simply states that a set of attributes of the
contained class, are available -either directly, by means of delegation- or
explicitly (i.e. instanceOfB.memberA.Property) to clientsof the container
class. Also, the "has-a" relation between an aggreted class and its members
might be exclusively private, thus belonging to the internal class
definition.

If a Class A is only a container of only one instance of ClassB,there is no
sense in the existence of ClassA (just ClassB is enough), unless it is a
generic container class, in which case the "hasA" relation is polymorphic.

"Is-a" is a concept relative to the subordinate class, while "has-a" belongs
to the definition of the parent class. They are concepts applicable to two
different categories.


Graham Perkins

unread,
Nov 19, 2001, 6:55:38 AM11/19/01
to

Mats Helander wrote:
>
> I have a question on IS A and HAS A relationships:
>
> If a class "A" HAS A (sorry for the caps, don't mean to yell, but I'm under
> the impression that's how you write'em relationships, yes?) class B, and it
> declares that it "Implements" class B and then it delegates all the calls to
> "Implemented" members in class A to the members of its instance of B (well,
> static members would forward to class B, but you get what I mean,
> right?)...Then, sure there was more work for me to obtain all this, but for
> a user of my object A - will there be any "real" difference to if class A
> had an IS A relationship to class B? I'm gathering that that the work
> described above is more or less what the compiler does for you automagically
> when you declare an IS A relationship...?

What you describe here is the Decorator Pattern. See "Design Patterns"
by Gamma, Helm, Johnson and Vlissides. The clients of A may as well be
clients of B except for the fact that they get a little extra
functionality
that you have put in A.

It is definitely NOT what the compiler does automagically when you
declare IS-A relationship. The crucial difference in IS-A is that your
new
class adds extra attributes and methods, all of which are present in the
same scope.

Under the scheme you mention, there are two separate scopes. The B and
A
instances cannot access or update each other's encapsulated parts. In
fact,
the B object can't get at anything at all in A unless you pass a ref to
A
across in all the calls from A to B. But that would require B to be
designed to handle A, even before A had been thought of.

-------------+ http:/www.gperkins.co.uk/

Mats Helander

unread,
Nov 19, 2001, 8:22:37 AM11/19/01
to
> What you describe here is the Decorator Pattern. See "Design Patterns"
> by Gamma, Helm, Johnson and Vlissides. The clients of A may as well be
> clients of B except for the fact that they get a little extra
> functionality
> that you have put in A.
>
> It is definitely NOT what the compiler does automagically when you
> declare IS-A relationship. The crucial difference in IS-A is that your
> new
> class adds extra attributes and methods, all of which are present in the
> same scope.
>
> Under the scheme you mention, there are two separate scopes. The B and
> A
> instances cannot access or update each other's encapsulated parts. In
> fact,
> the B object can't get at anything at all in A unless you pass a ref to
> A
> across in all the calls from A to B. But that would require B to be
> designed to handle A, even before A had been thought of.
>
I must have gotten something very seriously wrong...

I thought an instance of the subclass and the instance of its superclass
did -not- share scope. Private members are not inherited and can be declared
again in the subclass with no conflict, right?

Let's say B is the superclass of A, and that B has a private method called
"testMe()". Now, if I add a method "testMe()" to the subclass A, then I
wouldn't actually be overriding the "testMe()" member of A, since only
public members are inherited, yes?
And if I don't inherit it, I can't access it via "super.testMe()", right?

And if I override a public member, I can still call the original via
'super', yes?

And the 'super', in it's turn, will have no way of accessing the members of
the "subobject", just like you correctly observe will be the case in my
scheme...All of this is, in my book, the same as saying that they do not
share scope...

What am I missing???

/Best Regards, Mats Helander


John A. Byerly

unread,
Nov 19, 2001, 10:35:02 AM11/19/01
to
"Mats Helander" <ma...@urbantalk.se> wrote in message
news:3bf6...@news.wineasy.se...


No offence, but I was having trouble following your question. So if this
answer does not appear to be appropriate, feel free to ignore it!

The is-a relationship is one in which one object can be treated as another.
After all, if B is-a A, when you need an A, supplying an B should be
acceptable. For instance, if I have a Printer class, I can say that a
Lexmark is-a Printer. Any function that needs to operate on a Printer will
accept a Lexmark with no problem.

The has-a relationship simply means that one object needs to access another.
If the relationship between A and B is simply that A delegates to B, this
certainly could be a has-a relationship. Of course, there are degress of
has-a as well. For instance, does A _own_ B, or does it just have a
reference to B? In other words, should B cease to exist when A is
destroyed? If so, then A owns B, otherwise, A just has a reference to B.
But A owning B does not mean that B is-a A.

The long and short of it is this: Determine what makes sense conceptually.
I have found that this approach helps to answer the type of question you
pose.

JAB

--
--------------------------------------------------------
John A. Byerly
Engineered Software Solutions, Ltd.
http://www.ess-quality.com

Graham Perkins

unread,
Nov 19, 2001, 11:09:52 AM11/19/01
to
Mats Helander wrote:
> I thought an instance of the subclass and the instance of its superclass
> did -not- share scope.

Quite right. However, *all* methods within instance of a subclass,
including inherited methods, share the same scope. Which is, the
set of all methods and attributes declared in that subclass and all
its superclasses.

> Private members are not inherited and can be declared
> again in the subclass with no conflict, right?

In C++ and Java private members ARE inherited but cannot be accessed,
altered, or overriden. The subclass instance still has methods which
use those private members, so they must still be there!

In Eiffel and Smalltalk there is no such construct.

> Let's say B is the superclass of A, and that B has a private method called
> "testMe()". Now, if I add a method "testMe()" to the subclass A, then I
> wouldn't actually be overriding the "testMe()" member of A,

That's right.

> since only public members are inherited, yes?

Nope! All members are inherited, but only public and protected members
accessible. You have created an overload, with class membership being
used to disambiguate references.

> And if I don't inherit it, I can't access it via "super.testMe()", right?

You can't access it via "super.testMe()" because the rule for private
says you can's access it via "super.testMe()". But it's still there,
so you must have inherited it!

> And if I override a public member, I can still call the original via
> 'super', yes?

Yes.

> And the 'super', in it's turn, will have no way of accessing the
> members of the "subobject",

Yes it will. If it invokes a method that it knows about, but which
has been overridden in the subclass, then the override will be invoked.
That is how Template Pattern works.

> All of this is, in my book, the same as saying that they do not
> share scope...

I hope I've explained the small error in each of your statements that
leads one to conclude that they share scope.

Of course, separate instances of different classes don't share
scope, regardless of whether they are related by inheritance or not.

I'm saying that all methods of a class, including inherited ones,
share the same scope. And that shared scope includes all the members
of that class, including the inherited ones.

"private" visibility is a minor wrinkle that effects how new
code can refer to previous declarations, but it doesn't affect
the presence or absence of the "private" features.

-------------+ http:/www.gperkins.co.uk/

Dave Harris

unread,
Nov 19, 2001, 1:25:00 PM11/19/01
to
gper...@gperkins.co.uk (Graham Perkins) wrote (abridged):

> > Private members are not inherited and can be declared
> > again in the subclass with no conflict, right?
>
> In C++ and Java private members ARE inherited but cannot be accessed,
> altered, or overriden. The subclass instance still has methods which
> use those private members, so they must still be there!

Actually, in C++, private members can be overridden. Eg:

class Base {
public:
void publicMethod() {
privateMethod();
}

private:
virtual void privateMethod();
};

class Derived : public Base {
private:
void privateMethod() {
cout << "How did I get here?"
}
};

Base *pBase = new Derived();
pBase->publicMethod();

will print the message. Even though Derived::privateMethod() is private
and not declared virtual. "Private" is leaky.

Some people see this as a virtue; ie that access control and overriding
are orthogonal. In my view it means C++ does not provide full information
hiding. There is no easy way for Derived to declare a function that will
ensure Base cannot call it.

Java, however, works as you describe.

Dave Harris, Nottingham, UK | "Weave a circle round him thrice,
bran...@cix.co.uk | And close your eyes with holy dread,
| For he on honey dew hath fed
http://www.bhresearch.co.uk/ | And drunk the milk of Paradise."

@objectmentor.com Robert C. Martin

unread,
Nov 19, 2001, 11:53:58 PM11/19/01
to
On 17 Nov 2001 19:43:49 CET, "Mats Helander" <ma...@urbantalk.se>
wrote:

>I have a question on IS A and HAS A relationships:
>
>If a class "A" HAS A (sorry for the caps, don't mean to yell, but I'm under
>the impression that's how you write'em relationships, yes?) class B, and it
>declares that it "Implements" class B and then it delegates all the calls to
>"Implemented" members in class A to the members of its instance of B (well,
>static members would forward to class B, but you get what I mean,
>right?)...Then, sure there was more work for me to obtain all this, but for
>a user of my object A - will there be any "real" difference to if class A
>had an IS A relationship to class B? I'm gathering that that the work
>described above is more or less what the compiler does for you automagically
>when you declare an IS A relationship...?

The difference is in the details. At a very general level the two
forms are equivalent. But at the detailed level they are not. For
example, you could tell the two apart in C++ is you used dynamic_cast.
In Java you could tell the two apart if you used instanceof or a cast.

Having said that, some OO languages, use the mechanism you describe to
implement inheritance.


Robert C. Martin | "Uncle Bob" | Software Consultants
Object Mentor Inc. | rma...@objectmentor.com | We'll help you get
PO Box 5757 | Tel: (800) 338-6716 | your projects done.
565 Lakeview Pkwy | Fax: (847) 573-1658 | www.objectmentor.com
Suite 135 | | www.XProgramming.com
Vernon Hills, IL, | Training and Mentoring | www.junit.org
60061 | OO, XP, Java, C++, Python|

"One of the great commandments of science is:
'Mistrust arguments from authority.'" -- Carl Sagan

@objectmentor.com Robert C. Martin

unread,
Nov 20, 2001, 12:00:41 AM11/20/01
to
On 17 Nov 2001 19:43:49 CET, "Mats Helander" <ma...@urbantalk.se>
wrote:

>I have a question on IS A and HAS A relationships:

The ISA and HASA relationships are poorly named IMHO. They came from
the AI folks twenty years ago, and migrated into the OO domain because
the relationships between OO structures had certain similarities to
the knowledge networks the AIers were using.

Unfortunately, the term ISA and HAS are not well defined; and their
english connotation is not appropriate for OO relationships. ISA, for
example, is not a good name for inheritance. There are many cases
where the sentence "A ISA B" does not imply that A inherits from B.
The same can be said for "HASA". If you use the terms you have to use
them with poetic license.

I know we've been through the dreaded circle/elipse problem too many
times to count; but it's a perfect example of where the English
connotation of ISA fails. It makes perfect sense to say that a circle
ISA elipse (even though the grammar is pretty poor). On the other
hand, most of us agree that a circle class should not inherit from an
elipse class; since it is a violation of the LSP (Liskov Substitution
Principle).

HASA has its own similar problems. What does HAS mean. Is it
strongly related to the verb "to have"; or is there some other
connotation? Does it imply ownership? Does it imply responsibility?
Does it reply internal containment; or simply containment of a
reference?

Shayne Wissler

unread,
Nov 20, 2001, 12:01:52 AM11/20/01
to
Why do you ask this question? Are you simply trying to understand how the
compiler implements inheritance?

"Mats Helander" <ma...@urbantalk.se> wrote in message
news:3bf6...@news.wineasy.se...

Shayne Wissler

unread,
Nov 20, 2001, 12:13:30 AM11/20/01
to

"Robert C. Martin" <rmartin @ objectmentor . com> wrote in message
news:1fojvto7krsqhflkk...@4ax.com...

> Unfortunately, the term ISA and HAS are not well defined; and their
> english connotation is not appropriate for OO relationships. ISA, for
> example, is not a good name for inheritance. There are many cases
> where the sentence "A ISA B" does not imply that A inherits from B.

For example?

> The same can be said for "HASA". If you use the terms you have to use
> them with poetic license.

Example?

> I know we've been through the dreaded circle/elipse problem too many
> times to count; but it's a perfect example of where the English
> connotation of ISA fails. It makes perfect sense to say that a circle
> ISA elipse (even though the grammar is pretty poor). On the other
> hand, most of us agree that a circle class should not inherit from an
> elipse class; since it is a violation of the LSP (Liskov Substitution
> Principle).

1. Circles and ellipses aren't software, so the example isn't relevant
without more information about the system that has so-called "circles" and
"ellipses".
2. The reason for the LSP is so we can reason--using the concept "isa" in
the sense we normally do--about software. If "isa" isn't valid, then neither
is LSP.
3. If we presume a graphics system, there is no necessary violation of LSP
to derive circle from ellipse. It depends on your implementation.

> HASA has its own similar problems. What does HAS mean. Is it
> strongly related to the verb "to have"; or is there some other
> connotation? Does it imply ownership? Does it imply responsibility?
> Does it reply internal containment; or simply containment of a
> reference?

In Java there is no way to express "has". In C++, it is quite obvious what
"has" means:

class X {
int a;
double b[100];
}

X has a and b. I.e., the elements a and b are part of and integral to X.
There's no difference semantically than what we mean when we say a car has a
door.


Shayne Wissler

univ...@radix.undonet

unread,
Nov 20, 2001, 2:15:56 AM11/20/01
to

RMartin's take, or rather inability to take like the averager person or
programmer, is an obvious symptom and perhaps cause of his inability to
"embrace" a model of holistic system design prior to the bulk of high
level implementation.

Elliott
--
http://www.radix.net/~universe ~*~ Enjoy! ~*~
Hail OO Modelling! * Hail the Wireless Web!
@Elliott 2001 my comments ~ newsgroups+bitnet OK


Mats Helander

unread,
Nov 19, 2001, 11:28:30 AM11/19/01
to

John A. Byerly <jbyerly@ess-quality_remove.com> skrev i
diskussionsgruppsmeddelandet:tvi9t7o...@corp.supernews.com...

Absolutely no offence taken! I got a reply from Graham Perkins that set my
thinking straight. Apart from my inabilites with respects to expressing
myself, I had gotten the whole thing wrong...no wonder it didn't make much
sense!

Your response, however, does. And it points to one thing I'd forgotten, the
need for the constructor and deconstructor of the subclass to create and
destroy the delegated-to instance of the superclass.

Thanks!

/Best Regards, Mats Helander

Mats Helander

unread,
Nov 19, 2001, 11:17:37 AM11/19/01
to

Graham Perkins <gper...@gperkins.co.uk> skrev i
diskussionsgruppsmeddelandet:3BF92ECF...@gperkins.co.uk...

> Mats Helander wrote:
> > I thought an instance of the subclass and the instance of its superclass
> > did -not- share scope.
>
> Quite right. However, *all* methods within instance of a subclass,
> including inherited methods, share the same scope. Which is, the
> set of all methods and attributes declared in that subclass and all
> its superclasses.
>

I didn't quite get it just yet, but reading the rest of your reply did, see
below...

> > Private members are not inherited and can be declared
> > again in the subclass with no conflict, right?
>
> In C++ and Java private members ARE inherited but cannot be accessed,
> altered, or overriden. The subclass instance still has methods which
> use those private members, so they must still be there!
>
> In Eiffel and Smalltalk there is no such construct.
>
> > Let's say B is the superclass of A, and that B has a private method
called
> > "testMe()". Now, if I add a method "testMe()" to the subclass A, then I
> > wouldn't actually be overriding the "testMe()" member of A,
>
> That's right.
>
> > since only public members are inherited, yes?
>
> Nope! All members are inherited, but only public and protected members
> accessible. You have created an overload, with class membership being
> used to disambiguate references.

<Angel choir>
This is the point where it all became clear to me! Thank you so much! I've
not been able to get that from any OO book I've read! This will cause many
changes in my use of the vocabulary, and suddenly it all seems more
intelligeble...I'm awed. So that's how it's seen....

> > And if I don't inherit it, I can't access it via "super.testMe()",
right?
>
> You can't access it via "super.testMe()" because the rule for private
> says you can's access it via "super.testMe()". But it's still there,
> so you must have inherited it!

I'm nat going against this, given my newfound wisdom (see above), but to
show where I went wrong, I thought that it was (as you say) because the
rules said so, but (again) I thought this was because you were only
"secretly" holding a reference to a separate super object, to which the
calls in the inherited members were delegated. But now I've seen the light
(I think).

> > And if I override a public member, I can still call the original via
> > 'super', yes?
>
> Yes.

Overloading again? super.someMethod() is actually represented in the
subclass as overloading this.someMethod()? Again, I thought it was just a
delegational call (but stand corrected)...

> > And the 'super', in it's turn, will have no way of accessing the
> > members of the "subobject",
>
> Yes it will. If it invokes a method that it knows about, but which
> has been overridden in the subclass, then the override will be invoked.
> That is how Template Pattern works.

I'm with you.

> > All of this is, in my book, the same as saying that they do not
> > share scope...
>
> I hope I've explained the small error in each of your statements that
> leads one to conclude that they share scope.

Yes. Indeed. Again, thanks! My book is now updated accordingly.

> Of course, separate instances of different classes don't share
> scope, regardless of whether they are related by inheritance or not.
>
> I'm saying that all methods of a class, including inherited ones,
> share the same scope. And that shared scope includes all the members
> of that class, including the inherited ones.
>
> "private" visibility is a minor wrinkle that effects how new
> code can refer to previous declarations, but it doesn't affect
> the presence or absence of the "private" features.
>

So, basically, all the inherited members are also "reimplemented" in the
subclass, making it "self-contagious"...Right?

/Best Regards, Mats Helander.


Warren Zeigler

unread,
Nov 20, 2001, 11:39:37 AM11/20/01
to
"Mats Helander" <ma...@urbantalk.se> wrote in message
news:3bf9...@news.wineasy.se...


From the various posts, I think you are closer to "getting it, but still
having a vew probems"

>I thought that it was (as you say) because the
>rules said so, but (again) I thought this was because you were only
>"secretly" holding a reference to a separate super object, to which the
>calls in the inherited members were delegated. But now I've seen the light

New OO people seem to always trip up on this. Our discussing "accessing
methods of the parent class," etc, is really not true. We access methods
DEFINED in the parent class, but once you do "new," they are all part of one
object.

I can't count the number of times programmers have asked "Is it accessing a
hidden instance of the parent object?"

To clarify - think of it this way:
When you say "new" to the concrete class that inherits:
1) As far as allocation of memory for the various variables, all of the
class definitions are consolidated (collapsed) into a single concrete class.
It is as if you did a cut and past, putting everything in the concrete
class. If you have name duplicates, BOTH exist.
2) As far as visibility is concerned, the language rules apply for private
and protected data members, and private, protected, overridden and
polymorphic methods, but don't let that confuse you. There is only one
object created. You are not accessing members of the parent object if the
method or data were defined there. You are accessing data in the one and
only one object created by new, parts of which happened to be defined in the
parent class.

"new" has nothing to do with method inheritance. All code is generated for
all methods, whether they were defined in the parent or concrete class.
Which code (method) is accessed depends on language rules (including the
type of the reference in some languages) and any runtime polymorphic
mechanism that may exist.

One last perspective:
1) When "new" executes, memory is allocated for the variables in the object.
The variables created are the sum total of the variables defined in the
concrete class and all classes inherited by the concrete class. They are
allocated in ONE block, creating ONE object, with parts defined in different
classes. (Most runtime polymorphism mechanisms also take a little space, but
it is all part of the one allocated object.)
2) The methods used to access this data is defined by language rules for
visibility, overloading, overriding and polymorphism.

Did this help?

--
Warren R. Zeigler Sr.
Understanding Objects - The most complete object basics class today.
It's the class knowledgeable managers have been looking for.
URL: http://www.UnderstandingObjects.com


L. F. Hall

unread,
Nov 20, 2001, 12:40:20 PM11/20/01
to
From: Robert C. Martin <rmartin @ objectmentor . com>
Message-ID: <1fojvto7krsqhflkk...@4ax.com>

[snip]


> I know we've been through the dreaded circle/elipse problem too many
> times to count; but it's a perfect example of where the English
> connotation of ISA fails. It makes perfect sense to say that a circle
> ISA elipse (even though the grammar is pretty poor). On the other
> hand, most of us agree that a circle class should not inherit from an
> elipse class;

Okay.

> since it is a violation of the LSP (Liskov
Substitution
> Principle).

No. This is a repeat of the blemish in your 1996 paper on LSP. ISA
does not violate Barbara Liskov's statement of the LSP. Please,
stand tall and write "oops" about that minor defect in a valid work, so
we better understand sound program design advice.

Supporting citation for my blunt response:
From Re: On LSP *is_a*, rel_P*: was Re: "is a" relationship
between enumerated types? on clcm in July 2001.

>From: "Jake Holland" <jhol...@ixiacom.com>

> > "L. F. Hall" <p...@eot.com> wrote in message
> > news:ZugZ6.1629$oF3.4...@news7.onvoy.net...
> > [snip]
> > > LSP is *not* violated in Robert Martin's sample code. His explanation
> > > may be "clear," but it is not in accord with LSP. Instead, his design
> > > principle that classes should not be corrupted if mistakenly passed to
> > > their base class member functions is violated. So, he has made a

> > [snip]
> > Ah, I think I see the source of confusion.
> > http://www.objectmentor.com/publications/lsp.pdf, Page 4, paragraph 3
> > (right under the "f" function), where he says "This is a clear violation
> > of LSP." The f function doesn't violate LSP, it violates the Square
> > class invariant, and therefore it looks like there's an error in the
> > paper. If that's what you're saying, I agree.

> That's what I'm saying. Preservation of the Square class invariant in
> this example is a more restrictive (protective) design guideline than LSP.

> > The "fix" proposed for illustration, in which Rectangle::SetWidth and
> > SetHeight are virtual, is the version which actually violates the LSP,
> > as demonstrated by the "g" function on page 5, according to my
> > understanding. It was this part of the paper (extending on to page 6)
> > to which I was referring when I said his sample code violates the LSP
> > and that this was clearly explained. Sorry for the confusion.

> Agreed. The virtual functions modify the base class behavior through
> the derived class. RM, himself, notes the "fix" violates the Open-Closed
> principle as he introduces it on pg 4b.

Please do not consider this acrimonious squabbling. Some of the history
of science is cooperative building of understanding among persons of
good will. Many of us would benefit from your correction of this minor
blemish and its removal from present discussions.

Tnx for the moments,
Len


Shayne Wissler

unread,
Nov 20, 2001, 1:05:26 PM11/20/01
to

<univ...@radix.UNDOnet> wrote in message
news:9tcvvc$bb3$1...@news1.Radix.Net...

> RMartin's take, or rather inability to take like the averager person or
> programmer, is an obvious symptom and perhaps cause of his inability to
> "embrace" a model of holistic system design prior to the bulk of high
> level implementation.
>
> Elliott

If you want to write a post on what "holistic system design" is and why it
relates to an "inability to talk like the average person" (and why this
matters), then write it. Otherwise, all you've done is devalued this
newsgroup by making inappropriate, gratuitous ad hominems.


Shayne Wissler

Mats Helander

unread,
Nov 20, 2001, 2:26:31 PM11/20/01
to
Thank you! Most enlightening! And I'm very happy to get this straight,
because I always thought it was a bit wierd...

Actually, I've read a few books on the topic, and what I've fouund on the
web...do you have any suggested book (notice the lack of pluralis) or url:s
that put things as clearly as you just have?

/Best Regards, Mats Helander

Mats Helander

unread,
Nov 20, 2001, 2:34:36 PM11/20/01
to
>
> The difference is in the details. At a very general level the two
> forms are equivalent. But at the detailed level they are not. For
> example, you could tell the two apart in C++ is you used dynamic_cast.
> In Java you could tell the two apart if you used instanceof or a cast.
>
> Having said that, some OO languages, use the mechanism you describe to
> implement inheritance.
>

Really? Could you name a few?

/Best Regards, Mats Helander


Mats Helander

unread,
Nov 20, 2001, 2:58:46 PM11/20/01
to

Shayne Wissler <thal...@yahoo.com> skrev i
diskussionsgruppsmeddelandet:4tlK7.32633$RG1.16...@news1.rdc1.sfba.home.c
om...

> Why do you ask this question? Are you simply trying to understand how the
> compiler implements inheritance?

Well, I'm building an OO tool, and here comes the funny part:

You know what I got wrong about inheritence. But as I said, I always found
it strange. So strange, in fact, that I decided I couldn't have it! So I
built the tool on the principle you've described instead, thinking "OO
purists may call me their names, but I'll be darned if I'll do it any other
way..."

I thought to myself that I could motivate in the documentation why I made
these choises. Then I came here to gain a better understanding of the issue
(thus my question) so I wouldn't sound too confused in that doc.

Obviously, I'm very pleased with my recent learnings! Thank you all!

If I may bore you further, I'd like to ask one more question:

The reason I got to thinking about these things has very much to do with you
remarks about the object being just one block of memory. I'm making a tool
that maps objects to rdbms, and so I have to think about the same aspect.

I decided that a concrete object should have all their properties collected
at the table level (just like the one-memory-block principle) or their would
be no end to the horrors that would follow.

But now, to my question: If you have a part in the constructor of a class
that creates an entry to a table, say like this

<Part of Person class's constructor>
conn.Execute "INSERT INTO tblPerson...."

Then with the (as I understand it to be) common practice of calling the
parent's constuctor from the constructor of the subclass, as:

<Part of Employee class's constructor>
<Call super's constructor>
conn.Execute "INSERT INTO tblEmployee...."

Then the employee object will be represented in two different tables in the
database, breaching the concept of the "one-lump object".

Is this realistic, or am I missing something in how it's normally done? As I
said, I went through pains to make my tools make sure that two tables aren't
used like this (and I had to do it just by avoiding simply calling up a
hidden instance of the superclass and delegate, all inherited members had to
be modified), so I'm happy to learn that it doesn't violate OO principles!

/Best Regards, Mats Helander


Warren Zeigler

unread,
Nov 20, 2001, 8:28:11 PM11/20/01
to
"Mats Helander" <ma...@urbantalk.se> wrote in message
news:3bfa...@news.wineasy.se...

> Thank you! Most enlightening! And I'm very happy to get this straight,
> because I always thought it was a bit wierd...
>
> Actually, I've read a few books on the topic, and what I've fouund on the
> web...do you have any suggested book (notice the lack of pluralis) or
url:s
> that put things as clearly as you just have?
>
> /Best Regards, Mats Helander

Your welcome, and thanks for the kind words.

No, this is a gap in the book and training market. Now that I am done w/ my
manual, I am about to convert it to a book.

@objectmentor.com Robert C. Martin

unread,
Nov 21, 2001, 1:01:33 AM11/21/01
to
On Tue, 20 Nov 2001 05:13:30 GMT, "Shayne Wissler"
<thal...@yahoo.com> wrote:

>
>"Robert C. Martin" <rmartin @ objectmentor . com> wrote in message
>news:1fojvto7krsqhflkk...@4ax.com...
>
>> Unfortunately, the term ISA and HAS are not well defined; and their
>> english connotation is not appropriate for OO relationships. ISA, for
>> example, is not a good name for inheritance. There are many cases
>> where the sentence "A ISA B" does not imply that A inherits from B.
>
>For example?

An integer ISA complex number. However, no sane programmer would
normally build an integer class that inherits from a complex class.
At least not in any of the conventional OO languages that are
currently in use; or were in use when the term ISA was mapped to OO.

>> I know we've been through the dreaded circle/elipse problem too many
>> times to count; but it's a perfect example of where the English
>> connotation of ISA fails. It makes perfect sense to say that a circle
>> ISA elipse (even though the grammar is pretty poor). On the other
>> hand, most of us agree that a circle class should not inherit from an
>> elipse class; since it is a violation of the LSP (Liskov Substitution
>> Principle).
>
>1. Circles and ellipses aren't software, so the example isn't relevant
>without more information about the system that has so-called "circles" and
>"ellipses".

I have actually reviewed designs of system where there was, indeed, a
circle class that tried to inherit from an arc class. The domain was
computational geometry. The authors felt that the ISA rule meant that
a Circle should inherit from an Arc. Clearly there are problems with
this view. An Arc must have an angle variable, that a Circle doesn't
need.

Regardless of whether circle/elipse is a software problem or not, it
has many analogs in other software domains. The issues are still
relevant. Circle/Elipse is just an example of the kinds of problems
that assuming ISA means inheritance can cause.

>2. The reason for the LSP is so we can reason--using the concept "isa" in
>the sense we normally do--about software. If "isa" isn't valid, then neither
>is LSP.

If you define "isa" to mean LSP then the issue goes away. If, on the
other hand, you define ISA to mean "is a" as in english; and then
equate it to inheritance, you end up with circle/elipse problems.

>3. If we presume a graphics system, there is no necessary violation of LSP
>to derive circle from ellipse. It depends on your implementation.

There are ways to avoid the LSP violation; but they are very
constraining. One has to make the classes immutable; or employ some
other draconian measure. This seems like a lot of inconvenience just
to keep the use of ISA consistent with English "is a" and implemented
with inheritance.

>> HASA has its own similar problems. What does HAS mean. Is it
>> strongly related to the verb "to have"; or is there some other
>> connotation? Does it imply ownership? Does it imply responsibility?
>> Does it reply internal containment; or simply containment of a
>> reference?
>
>In Java there is no way to express "has". In C++, it is quite obvious what
>"has" means:
>
>class X {
> int a;
> double b[100];
>}

That's one definition. It's not the definition Booch used in "Object
Oriented Analysis and Design". It's also not the definition that the
three amigos used in the early versions of UML.

Booch and early UML defined HASA to mean "able to send messages to".
This was most often implemented as an instance variable holding a
pointer, or a reference. It was sometimes implemented as an instance
variable holding a value, as above. It was even implemented as an
argument to a method on rare occasions.


>
>X has a and b. I.e., the elements a and b are part of and integral to X.
>There's no difference semantically than what we mean when we say a car has a
>door.

Using simple english transtive verbs to describe OO relationships is,
IMHO, naive. OO relationships have very particular semantics that map
only very crudely to those english verbs.

@objectmentor.com Robert C. Martin

unread,
Nov 21, 2001, 1:15:40 AM11/21/01
to


I'm having trouble seeing the flaw. The violation in both cases is in
the Square class. Square is not substitutable for valid clients of
Rectangle. Both f and g are valid clients of Rectangle that do not
violate any of Recatangles implied contracts. Neither f nor g know
anything at all about Square, nor should they. Yet if a Square is
passed into these functions, in the guise of a Rectangle; confusion
results. Either the Square is corrupted (in the f case) or the
client's expectations are violated. It is not g nor f that violate
the LSP. Those functions don't violate anything at all. It is the
implementation of Square that violate the LSP.

Shayne Wissler

unread,
Nov 21, 2001, 2:34:32 AM11/21/01
to

"Robert C. Martin" <rmartin @ objectmentor . com> wrote in message
news:tsfmvtc7ceviu7oaj...@4ax.com...

> >For example?
>
> An integer ISA complex number. However, no sane programmer would
> normally build an integer class that inherits from a complex class.

You're confusing a software integer with a mathematical integer. They are
two entirely different things. I don't see how this discussion can go
anywhere if you won't distinguish between software units and other kinds of
units.


Shayne Wissler

Shayne Wissler

unread,
Nov 21, 2001, 11:18:38 AM11/21/01
to

"Robert C. Martin" <rmartin @ objectmentor . com> wrote in message
news:tsfmvtc7ceviu7oaj...@4ax.com...

> If you define "isa" to mean LSP then the issue goes away. If, on the
> other hand, you define ISA to mean "is a" as in english; and then
> equate it to inheritance, you end up with circle/elipse problems.

What do you think "is a" in English means?


Shayne Wissler

univ...@radix.undonet

unread,
Nov 21, 2001, 12:16:04 PM11/21/01
to
Robert C. Martin <rmartin @ objectmentor . com> wrote:
> On Tue, 20 Nov 2001 05:13:30 GMT, "Shayne Wissler"
> <thal...@yahoo.com> wrote:
>
>>
>>"Robert C. Martin" <rmartin @ objectmentor . com> wrote in message
>>news:1fojvto7krsqhflkk...@4ax.com...
>>
>>> Unfortunately, the term ISA and HAS are not well defined; and their
>>> english connotation is not appropriate for OO relationships. ISA, for
>>> example, is not a good name for inheritance. There are many cases
>>> where the sentence "A ISA B" does not imply that A inherits from B.

>>For example?

> An integer ISA complex number.

In whose math? I've never heard that in 2nd year calculus, linear
algebra, statistics, etc.

If anything complex is built from real and imaginary numbers.

And it really depends on math, or other domain context, as to what the
relationship should be.

> However, no sane programmer would
> normally build an integer class that inherits from a complex class.
> At least not in any of the conventional OO languages that are
> currently in use; or were in use when the term ISA was mapped to OO.

For A and B of *any 2 things* in some cases B shouldn't be inherited from
A, B should be inherited from A, or B should be an object instance of A.

Aside from how integer relates to complex, inheriting one thing from
another depends on the actual domain, project use cases, potential
hardware, potential software, etc.

univ...@radix.undonet

unread,
Nov 21, 2001, 12:25:50 PM11/21/01
to

Good point. Commonality is commonality, is commonality.

While LSP demands a strict interpretation of commonality, commonality is
clearly the underlying idea in "everyday" English. That shouldn't be hard
for people to realize, but XP/Agility folk never fail to surprise.

Graham Perkins

unread,
Nov 21, 2001, 12:28:01 PM11/21/01
to
> Actually, in C++, private members can be overridden. Eg:

Good grief! I've just checked ARM and you're quite correct
of course. What a foolish piece of design!

Moreover, I see you can override any method ande declare
different visibility in the derived class.

What is the point? If you're reducing the visibility,
client can simply upcast to increase again.

> In my view it means C++ does not provide full information
> hiding. There is no easy way for Derived to declare a function
> that will ensure Base cannot call it.

nor vice-versa.


-------------+ http:/www.gperkins.co.uk/

Graham Perkins

unread,
Nov 21, 2001, 12:37:02 PM11/21/01
to
> So, basically, all the inherited members are also "reimplemented"
> in the subclass, making it "self-contagious"...Right?

In the case of C++, the term "self contagious" seems ideal :-)

But yes, you can think of it as "re-implemented". Personally
I find it easy to think of all the methods as "re-implemented"
per instance.

In the case of instances, there is hidden "this" reference
going along with all the method calls in order to provide
a scope so that each instance behaves as if it had its own
methods.

In the case of subclasses, the virtual method table is copied
and then extended with extra references to the code for the
new functions. (or old references are replaced, in the case
of overrides). Also, the attribute template is copied and
extended.

More dynamic systems like Smalltalk have to be different
'cos they allow you to edit a superclass while its subclass
instances are still live.

good luck,
graham

-------------+ http:/www.gperkins.co.uk/

Mats Helander

unread,
Nov 21, 2001, 10:43:29 AM11/21/01
to
>Yet if a Square is
> passed into these functions, in the guise of a Rectangle; confusion
> results. Either the Square is corrupted (in the f case) or the
> client's expectations are violated.

The way I program (not out to say right or wrong, just to say that you can
see it differently) I wouldn't have problems with Squares passed to
functions expecting Rectangles, but I might the other way around.

I don't see it to be 'necessary' OO practice to subclass in order to add
members, some situations justify adding subclasses to 'incapacitate' members
through, well, call it business rules.

To me, a Square inherits from a rectangle, and adds the business rule (in
the property accessor methods, most likely) that whenever you change either
the Width or Height, both will take the supplied value. Why would I want to
do it like that?

Because I can't imagine all the uses clients of my objects might think up.
For instance: I probably wouldn't forget to add an "getArea()" method to my
Square and Rectangle classes. But assume that I did, in order to show how
clients may need to use my objects in unforseen ways. So, a function that
accepts a Square object and that needed the area would obviously take either
the Width or Height and square it. A function that accepted a Rectangle
would multiply the Height with the Width, and this wouldn't be a problem if
a Square was passed to it. But if you are able to pass a Rectangle to the
function that expects a Square, the function will proceed to use a false
value for the area.

Additionally, the function that accepts a Rectangle might make a check on
the object to see if it is actually a Square, and then tweak the area-calcs
to optimise it a bit (read just Height OR Width). It would then be checking
for a class above the expected one in the hierarchy, and so it could
reasonably know about it (it was obviously there before the subclass was
defined). On the other hand, If you want Rectangle to inherit from Square,
the function that expects a Square MUST include (if I forgot to include a
getArea() method) this kind of tweak, AND it must look downwards in the
hierarchy, in other words it must be prepared for classes that might have
yet to be defined.

That's the way I see it, I'm sure there's plenty of views....

/Best Regards, Mats Helander


Richard MacDonald

unread,
Nov 21, 2001, 12:48:42 PM11/21/01
to
<univ...@radix.UNDOnet> wrote in message
news:9tgngk$fs9$1...@news1.Radix.Net...

> Robert C. Martin <rmartin @ objectmentor . com> wrote:
> > On Tue, 20 Nov 2001 05:13:30 GMT, "Shayne Wissler"
> > <thal...@yahoo.com> wrote:
> >
> >>
> >>"Robert C. Martin" <rmartin @ objectmentor . com> wrote in message
> >>news:1fojvto7krsqhflkk...@4ax.com...
> >>
> >>> Unfortunately, the term ISA and HAS are not well defined; and their
> >>> english connotation is not appropriate for OO relationships. ISA, for
> >>> example, is not a good name for inheritance. There are many cases
> >>> where the sentence "A ISA B" does not imply that A inherits from B.
>
> >>For example?
>
> > An integer ISA complex number.
>
> In whose math? I've never heard that in 2nd year calculus, linear
> algebra, statistics, etc.

Perhaps you shouldn't have slept through high school algebra then.

> If anything complex is built from real and imaginary numbers.

Nope. 1+0i is a complex number. Note the integer(s).

> And it really depends on math, or other domain context, as to what the
> relationship should be.

Quite so. In this case, I think Robert was referring to the math domain.


Shayne Wissler

unread,
Nov 21, 2001, 2:51:53 PM11/21/01
to

<univ...@radix.UNDOnet> wrote in message
news:9tgo2u$fs9$2...@news1.Radix.Net...

> Shayne Wissler <thal...@yahoo.com> wrote:
> >
> > "Robert C. Martin" <rmartin @ objectmentor . com> wrote in message
> > news:tsfmvtc7ceviu7oaj...@4ax.com...
> >
> >> If you define "isa" to mean LSP then the issue goes away. If, on the
> >> other hand, you define ISA to mean "is a" as in english; and then
> >> equate it to inheritance, you end up with circle/elipse problems.
>
> > What do you think "is a" in English means?
>
> Good point. Commonality is commonality, is commonality.

Right--though I'd use the term "similarity." Commonality denotes common
parts, whereas "is a" implies similarity.


Shayne

Mats Helander

unread,
Nov 21, 2001, 12:51:37 PM11/21/01
to

Graham Perkins <gper...@gperkins.co.uk> skrev i
diskussionsgruppsmeddelandet:3BFBE63E...@gperkins.co.uk...

> > So, basically, all the inherited members are also "reimplemented"
> > in the subclass, making it "self-contagious"...Right?
>
> In the case of C++, the term "self contagious" seems ideal :-)
>
> But yes, you can think of it as "re-implemented". Personally
> I find it easy to think of all the methods as "re-implemented"
> per instance.
>
> In the case of instances, there is hidden "this" reference
> going along with all the method calls in order to provide
> a scope so that each instance behaves as if it had its own
> methods.

If I get this right, that means that:

myInstance.doStuff()

is in reality:

ClassOfMyInstance.doStuff(this) 'static method

where myInstance is passed to the 'this' parameter?


> In the case of subclasses, the virtual method table is copied
> and then extended with extra references to the code for the
> new functions. (or old references are replaced, in the case
> of overrides). Also, the attribute template is copied and
> extended.

Aha! So for a non-overriden inherited method, the virtual method table
points to the same address as for the method in the superclass, right? Thus
Scott Ambler's remark earlier that the "delegation" approach will cost an
extra jump for methods?

> More dynamic systems like Smalltalk have to be different
> 'cos they allow you to edit a superclass while its subclass
> instances are still live.

I created a (rather simple) OO system that allowed you to do that. The
lesson I learned was to never use something like that again! ;-) No,
seriously, it works fine for RAD prototyping, but IMO it's not as useful for
something that you're actually gonna deploy.

> good luck,
> graham

Thank you. And rest assured that your answers go promptly towards minimizing
my dependancy on luck, which I apreciate greatly!

> -------------+ http:/www.gperkins.co.uk/


@objectmentor.com Robert C. Martin

unread,
Nov 21, 2001, 4:26:47 PM11/21/01
to

And folks who insist that Circle classes must inherit from Elipse
classes are confusing geometric shapes with software.

This is precisely the point of the whole argument. The term ISA can
be applied to various domains, like mathematics and geometry. There
are concepts in those domains that can be mapped to software. A
geometric circle can be mapped to become class Circle in a software
application. However, the relationships in one domain may not map
well into the software domain. The ISA relationship between Circle
and Elipse in the geometry domain does not map well into the software
domain.

@objectmentor.com Robert C. Martin

unread,
Nov 21, 2001, 4:32:44 PM11/21/01
to

I think you need to ask Mr. Clinton.

It can mean a whole bunch of things.

* It can mean congruence: "That is an equilateral triangle".
* It can mean "is like": "comp.object is a pain in the ass."
* It can equality: "1+1 is 2"
* It can mean equivalence. "The man in that video is me."
* It can mean allegory: "Superman is me."

It's a term that can be used in many varicolored ways.

Shayne Wissler

unread,
Nov 21, 2001, 4:32:42 PM11/21/01
to

"Robert C. Martin" <rmartin @ objectmentor . com> wrote in message
news:uq6ovtskv7bqsqv0c...@4ax.com...

> >You're confusing a software integer with a mathematical integer. They are
> >two entirely different things. I don't see how this discussion can go
> >anywhere if you won't distinguish between software units and other kinds
of
> >units.
>
> And folks who insist that Circle classes must inherit from Elipse
> classes are confusing geometric shapes with software.
>
> This is precisely the point of the whole argument. The term ISA can
> be applied to various domains, like mathematics and geometry. There
> are concepts in those domains that can be mapped to software. A
> geometric circle can be mapped to become class Circle in a software
> application. However, the relationships in one domain may not map
> well into the software domain. The ISA relationship between Circle
> and Elipse in the geometry domain does not map well into the software
> domain.

There are many points here I disagree with. But the most important and
fundamental is the implicit assumption that "is a" doesn't apply to
software. Again, precisely what do you think the english usage means?


Shayne Wissler

@objectmentor.com Robert C. Martin

unread,
Nov 21, 2001, 4:57:55 PM11/21/01
to
On Wed, 21 Nov 2001 17:28:01 +0000, Graham Perkins
<gper...@gperkins.co.uk> wrote:

>> Actually, in C++, private members can be overridden. Eg:
>
>Good grief! I've just checked ARM and you're quite correct
>of course. What a foolish piece of design!
>
>Moreover, I see you can override any method ande declare
>different visibility in the derived class.
>
>What is the point? If you're reducing the visibility,
>client can simply upcast to increase again.

You can increase the accessibility of an element of a derivative; but
you cannot decrease it. That is, you cannot make an inherited member
less accessible than it's base.

Shayne Wissler

unread,
Nov 21, 2001, 4:58:00 PM11/21/01
to

"Robert C. Martin" <rmartin @ objectmentor . com> wrote in message
news:u07ovtg659tutb5av...@4ax.com...

> >What do you think "is a" in English means?

> It can mean a whole bunch of things.


>
> * It can mean congruence: "That is an equilateral triangle".
> * It can mean "is like": "comp.object is a pain in the ass."
> * It can equality: "1+1 is 2"
> * It can mean equivalence. "The man in that video is me."
> * It can mean allegory: "Superman is me."
>
> It's a term that can be used in many varicolored ways.

My, the imagination. You left out the relevant sense, interestingly enough:

* - A bird is a living organism.
- A mouse is a mammal.
- A toyota celica is a car.
- A car is a vehicle.

Now, precisely what do you think this sense of "is a" means?


Shayne Wissler

Mats Helander

unread,
Nov 21, 2001, 10:40:58 PM11/21/01
to
Ok, I warned you, I said it was thought provoking, so these thoughts are
highly unpolished...

I've been thinking about the "typing" issue and the limitations of the
standard "is a" inheritence, and I had some (moronic?) ideas that I don't
know if they're just plain nutty or if there's already plenty of work done
on this...What set me off was thinking about the statement "If it is a
Customer and it has purchased for more than 20.000$, it is a
ValuedCustomer..."

The basic idea is this: Could you have some sort of "conditional" or
"dynamic" types?

Could I create (in some experimental language, or perhaps in some
commonplace language, maybe I'm just ignorant) a type ValuedCustomer that
was defined to be "All objects of the type Customer that happen to satisfy
this.getTotalPurchasesSum() > 20.000" so that I can define a function that
accepted objects of type ValuedCustomer, whereupon the runtime makes a
"type" check to see if the conditions are met on the object that is passed
to the function...of course you wouldn't be able to catch any compile-time
errors this way, but nevertheless...

The possible value I would see to such a feature would be that you could add
more (implementation-independent) logic to the (pre-implementation) model.

Just a thought...

/Best Regards, Mats Helander

>
> Martin Fowler <fow...@acm.org> skrev i
> diskussionsgruppsmeddelandet:3bfc6829.2405790624@news.ne.mediaone.net...


> > On Wed, 21 Nov 2001 16:18:38 GMT, "Shayne Wissler"
> > <thal...@yahoo.com> wrote:
> >
> > >What do you think "is a" in English means?
> >

> > The confusion over "is a" is an old knotty problem in logic.
> >
> > Consider the following statements
> >
> > 1) Shep is a Border Collie
> > 2) A Border Collie is a Dog
> > 3) A Dog is an Animal
> > 4) A Border Collie is a Breed
> > 5) A Dog is A Species
> >
> > If I combine (1) and (2) I get Shep is a dog
> > (2) and (3) -> Border Collies are animals
> > (1), (2), (3) -> Shep is an animal
> >
> > these all make sense
> >
> > but
> >
> > (1), (4) -> Shep is a Breed
> > (2), (5) -> Border Collie is a species
> >
> > do not
> >
> > The reason some combinations work and some don't is because "is a"
> > means something different in the five statements. Some are
> > classifications (Shep is an instance of Border Collie) while some are
> > generalizations (Border Collie is a kind of Dog). The rules for
> > combining them are rigorous once you realize there are two different
> > relationships.
> >
> > (And yes, "is a" can mean other things too.)
> >
> > Apparantly it was only surprisingly recently ( 19th or 20th century,
> > if I remember correctly) before this was properly understood. It had
> > tangled up logic for a while.
> >
> > Martin
> >
>
>


Shayne Wissler

unread,
Nov 22, 2001, 12:53:41 AM11/22/01
to
The reason why you can't combine 1,4 and 2,5 is that the concepts Animal,
Dog, and Border Collie all denote the entity Shep (in this context), but the
concepts Breed and Species denote *concepts*: Border Collie and Dog,
respectively.

Take the standard syllogism:

All men are mortal
Socrates is a man
Therefore, Socrates is mortal.

The reason you can make the deduction that Socrates is mortal is that it is
implict in the major premise: "All men" is already referring to Socrates, as
he is one.

Your combining (1) and (2) amounts to this syllogism:

All Border Collies are Dogs (this refers to every Border Collie that has,
does, or ever will exist)


Shep is a Border Collie

Therefore, Shep is a Dog.

However, your (1) and (4) combination is trying to make this syllogism:

(All) Border Collie is a Breed (this refers to the Border Collie qua type of
Breed, not to all or even to any particular Border Collie)


Shep is a Border Collie

Therefore, Shep is a Breed.

This makes no sense, because the referent of Border Collie in the major
premise is not referred to in the minor premise. The major premise is
referring to the *type* Border Collie, not a group of actual Border Collies,
but the minor premise is referring to an actual Border Collie.

So basically your last two examples commit a logical fallacy (I don't know
the name of it offhand). The problem isn't the concept "is a", but not
keeping track of what the "is a"'s are referring to.


Shayne Wissler

"Martin Fowler" <fow...@acm.org> wrote in message
news:3bfc6829.2405790624@news.ne.mediaone.net...


> On Wed, 21 Nov 2001 16:18:38 GMT, "Shayne Wissler"
> <thal...@yahoo.com> wrote:
>
> >What do you think "is a" in English means?
>

Mats Helander

unread,
Nov 21, 2001, 11:08:46 PM11/21/01
to

peter_douglass <bai...@gis.net> skrev i
diskussionsgruppsmeddelandet:3bfd0315$1@tobjects....

>
> "Mats Helander" wrote:
>
> > Ok, I warned you, I said it was thought provoking, so these thoughts are
> > highly unpolished...
> >
> > I've been thinking about the "typing" issue and the limitations of the
> > standard "is a" inheritence, and I had some (moronic?) ideas that I
don't
> > know if they're just plain nutty or if there's already plenty of work
done
> > on this...What set me off was thinking about the statement "If it is a
> > Customer and it has purchased for more than 20.000$, it is a
> > ValuedCustomer..."
> >
> > The basic idea is this: Could you have some sort of "conditional" or
> > "dynamic" types?
>
> Yes, they are called dependent types. There is at least one experimental
> language that I know of with dependent types, called Cayenne
>
> http://www.cs.chalmers.se/~augustss/cayenne/
>
> --PeterD
>
> p.s. I hope you can read this. My posts from totally objects don't seem
to
> go everywhere, just some places :-(
>

I can read it! Thanks for the link, I'll follow it promptly! So I wasn't
mad, then... ;-)

/Best Regards, Mats Helander


Warren Zeigler

unread,
Nov 21, 2001, 9:35:52 PM11/21/01
to
> > In my view it means C++ does not provide full information
> > hiding. There is no easy way for Derived to declare a function
> > that will ensure Base cannot call it.
> nor vice-versa.
> -------------+ http:/www.gperkins.co.uk/

Stroustrup did not design the protection mechanism as a secure defense
mechanism, just a help.

Martin Fowler

unread,
Nov 21, 2001, 10:01:12 PM11/21/01
to
On Wed, 21 Nov 2001 16:18:38 GMT, "Shayne Wissler"
<thal...@yahoo.com> wrote:

>What do you think "is a" in English means?

The confusion over "is a" is an old knotty problem in logic.

Universe

unread,
Nov 21, 2001, 10:46:00 PM11/21/01
to
Robert C. Martin <rmartin @ objectmentor . com> wrote:
> On Wed, 21 Nov 2001 07:34:32 GMT, "Shayne Wissler"
> <thal...@yahoo.com> wrote:
>
>>
>>"Robert C. Martin" <rmartin @ objectmentor . com> wrote in message
>>news:tsfmvtc7ceviu7oaj...@4ax.com...
>>
>>> >For example?
>>>
>>> An integer ISA complex number. However, no sane programmer would
>>> normally build an integer class that inherits from a complex class.
>>
>>You're confusing a software integer with a mathematical integer. They are
>>two entirely different things. I don't see how this discussion can go
>>anywhere if you won't distinguish between software units and other kinds of
>>units.

> And folks who insist that Circle classes must inherit from Elipse
> classes are confusing geometric shapes with software.

Anybody who insists on anything regardless of context, just as you do by
insisting that all of reality can't be modelled in software, regardless of
software used, is confused at best.

Who are these people insisting Circle must inherit from Ellipse anyway?
I've never seen it.

Inheriting Circle from Ellipse can indeed work when properly designed
and coded. The lines of approach taken by Cauvin and Helander are highly
effective and doable ways of precisley inheriting Circle from Ellipse if
your domain and or use cases require that.

> This is precisely the point of the whole argument. The term ISA can
> be applied to various domains, like mathematics and geometry. There
> are concepts in those domains that can be mapped to software. A
> geometric circle can be mapped to become class Circle in a software
> application.

> ...However, the relationships in one domain may not map


> well into the software domain. The ISA relationship between Circle
> and Elipse in the geometry domain does not map well into the software
> domain.

You have not shown us this at all.

Your faulty, technocratic worldview that OO doesn't originate, or exist in
reality is what prompts you to periodically insist that certain things can
not be inherited from another.

But a) you haven't demonstrated it, and b) if it really exists or is a
good way to model a domain, and or use cases it can be done with enough
*fore*thought in design and coding. And c) most OO practioners
fundamentally see OO as Booch does in the first 3 chapters of his OOA&D,
which you have always disliked and argued against. Given this,
anything you did contribute to Booch methodology was ancillary and
secondary at best.

Universe

unread,
Nov 21, 2001, 10:52:30 PM11/21/01
to
Universe <univ...@radix.undonet> at RadixNet Internet


Robert C. Martin <rmartin @ objectmentor . com> wrote:

> "Shayne Wissler" wrote:

>>"Robert C. Martin" <rmartin @ objectmentor . com> wrote in message

>>> "Shayne Wissler" wrote:
>>> >For example?

>>> An integer ISA complex number. However, no sane programmer would
>>> normally build an integer class that inherits from a complex class.
>>> normally build an integer class that inherits from a complex class.

>>You're confusing a software integer with a mathematical integer. They are
>>two entirely different things. I don't see how this discussion can go
>>anywhere if you won't distinguish between software units and other kinds of
>>units.

> And folks who insist that Circle classes must inherit from Elipse
> classes are confusing geometric shapes with software.

Anybody who insists on anything regardless of context, just as you do
by insisting that all of reality can't be modelled in software,
regardless of software used, is confused at best.

BTW, who are these people insisting Circle must inherit from Ellipse
anyway? I've never read it.



Inheriting Circle from Ellipse can indeed work when properly designed
and coded. The lines of approach taken by Cauvin and Helander are

highly effective and doable ways of precisely inheriting Circle from


Ellipse if your domain and or use cases require that.

> This is precisely the point of the whole argument. The term ISA can
> be applied to various domains, like mathematics and geometry. There
> are concepts in those domains that can be mapped to software. A
> geometric circle can be mapped to become class Circle in a software
> application.

> ...However, the relationships in one domain may not map
> well into the software domain. The ISA relationship between Circle
> and Elipse in the geometry domain does not map well into the software
> and Elipse in the geometry domain does not map well into the software
> domain.

You have not shown us this at all.

Your faulty, technocratic world view that OO doesn't originate, or


exist in reality is what prompts you to periodically insist that
certain things can not be inherited from another.

But:
A.) you haven't demonstrated it, and
B.) if it really exists or is a good way to model a domain, and or


use cases it can be done with enough *fore*thought in design and

coding., and
C.) most OO "practioners" fundamentally see OO as Booch does in the


first 3 chapters of his OOA&D, which you have always disliked and
argued against.

Finally, given C.), anything you did contribute to Booch methodology

Mats Helander

unread,
Nov 21, 2001, 8:53:52 PM11/21/01
to
Now, this was thought provoking...

Just a thought though: the statement "A Dog is A Species" might not be
agreed upon so intuitively by non-OO:ers - perhaps we swallow statements
like that more easily because we are so used to the lack of better
resolution in the "is a" relationship?

/Best Regards, Mats Helander

Martin Fowler <fow...@acm.org> skrev i
diskussionsgruppsmeddelandet:3bfc6829.2405790624@news.ne.mediaone.net...

Mats Helander

unread,
Nov 21, 2001, 10:14:56 PM11/21/01
to
>
> Inheriting Circle from Ellipse can indeed work when properly designed
> and coded. The lines of approach taken by Cauvin and Helander are
> highly effective and doable ways of precisely inheriting Circle from
> Ellipse if your domain and or use cases require that.

It is a very important extention you add that I forgot in my post, the "if
your domain and or use cases require that"...

That's what it's all about.

/Best Regards, Mats Helander


@objectmentor.com Robert C. Martin

unread,
Nov 22, 2001, 12:25:33 PM11/22/01
to

It means "is a member of the set of"

A bird is a member of the set of living organisms.
A mouse is a member of the set of mammals.
etc...

Shayne Wissler

unread,
Nov 22, 2001, 1:10:38 PM11/22/01
to

"Robert C. Martin" <rmartin @ objectmentor . com> wrote in message
news:s5dqvt8fu0r6udg3p...@4ax.com...

> >* - A bird is a living organism.
> > - A mouse is a mammal.
> > - A toyota celica is a car.
> > - A car is a vehicle.
> >
> >Now, precisely what do you think this sense of "is a" means?
>
> It means "is a member of the set of"
>
> A bird is a member of the set of living organisms.
> A mouse is a member of the set of mammals.
> etc...

I think that meaning should do. So what's wrong with that sense as it
applies to inheritance? Is it that you don't see how to apply it, or is
there some other issue?


Shayne Wissler

Universe

unread,
Nov 22, 2001, 8:26:20 PM11/22/01
to
"Shayne Wissler" <thal...@yahoo.com> wrote:

><univ...@radix.UNDOnet> wrote in message

>> Shayne Wissler <thal...@yahoo.com> wrote:

>> > "Robert C. Martin" <rmartin @ objectmentor . com> wrote in message
>> >

>> >> If you define "isa" to mean LSP then the issue goes away. If, on the
>> >> other hand, you define ISA to mean "is a" as in english; and then
>> >> equate it to inheritance, you end up with circle/elipse problems.

>> > What do you think "is a" in English means?

>> Good point. Commonality is commonality, is commonality.

>Right--though I'd use the term "similarity." Commonality denotes common
>parts, whereas "is a" implies similarity.

I see that the concept of "commonality" underlies that of
"similarity". You can base "similarity" upon "commonality", but not
"commonality" upon "similarity", as I see it.

Things that are similar are similar because in some way they have
properties or features which can be abstracted out, to at minimum a
very basic, simple (high level) commonality.

Elliott
--
http://www.radix.net/~universe ~*~ Enjoy! ~*~
Hail OO Modelling! * Hail the Wireless Web!

@Elliott 2001 my comments ~ newsgroups+bitnet quote ok

@objectmentor.com Robert C. Martin

unread,
Nov 23, 2001, 1:04:57 AM11/23/01
to

Inheritance is not equivalent to set membership. Inheritance is a
relationship between two classes whereby the variables and functions
of the base class are accessible to the derived class as though they
were defined within the derived class.

One can say that all derivatives are members of the set of classes
that have the variables and functions of their base class. However
this is a very constrained form of set membership. No such constraint
is implied by "isa". Thus, while we can say that all circles are
elements of the set of all elipses, we cannot use that as proof, or
even evidence, that inheritance can or ought to be used between the
software class that represents a circle, and the software class that
represents an elipse.

The LSP further constrains those classes that conform to it, by
insisting that all derived classes be members of the set of classes
that can be used by clients of the base class. But once again this is
a very constrained form of set membership, and does not mean that all
ISA relationships can, or should, be represented by inheritance.

Graham Perkins

unread,
Nov 23, 2001, 6:29:36 AM11/23/01
to
> >Moreover, I see you can override any method and declare

> >different visibility in the derived class.
> >
> >What is the point? If you're reducing the visibility,
> >client can simply upcast to increase again.
>
> You can increase the accessibility of an element of a derivative; but
> you cannot decrease it. That is, you cannot make an inherited member
> less accessible than it's base.

Yes, I know that is the sensible language design decision, and the
one that Java and Eiffel enforce. But for C++ the ARM says otherwise,
and gives an example in which a public method is overriden as private.
It is then inaccessible to clients of the derived class unless they
upcast.

Perhaps I have an out-of-date edition :-(


-------------+ http:/www.gperkins.co.uk/

Graham Perkins

unread,
Nov 23, 2001, 6:43:39 AM11/23/01
to
Mats Helander wrote:

> If I get this right, that means that:
> myInstance.doStuff()
> is in reality:
> ClassOfMyInstance.doStuff(this) 'static method
> where myInstance is passed to the 'this' parameter?

Yes. Just about. That is the effect. But you could not
simulate objects directly in a modular language with such
a direct substitution. Between "myInstance.doStuff()" and
"ClassOfMyInstance.doStuff( myInstance )" there is the
problem of finding what exactly is the class of myInstance.

> Aha! So for a non-overriden inherited method, the virtual method table
> points to the same address as for the method in the superclass, right? Thus
> Scott Ambler's remark earlier that the "delegation" approach will cost an
> extra jump for methods?

Yes. With dynamic binding, every function call is a "gosub" to
an address retrieved from the VMT. Whereas in static binding each
function call is a gosub to an address known at compile time.

ISE's Eiffel compiler is very good at optimising many apparently
polymorphic calls into static binding.

The smalltalk approach has to be different since its dynamic
nature prevents compile-time analysis of static/dynamic binding.
However, at runtime the various loaders and JIT native coders
can "corral" lumps of code and optimise it.

[ re: runtime editing ]


> I created a (rather simple) OO system that allowed you to do that. The
> lesson I learned was to never use something like that again! ;-) No,
> seriously, it works fine for RAD prototyping, but IMO it's not as useful for
> something that you're actually gonna deploy.

I think smalltalkers would disagree!
For a start, the iterative prototyping approach can be used
for real development, not just RAD prototyping. Eg, see the
Objectory methodology. One thing I really like is that it
is extremely easy to develop deliverable code and test drivers
in parallel. In particular, we can build an object structure
to run tests against, and keep testing as we add more methods.
No need to rebuild the entire target object structure every
time we edit/add the methods.

And for another, the ability to update a system while it is
executing is quite an asset in some circumstances.


-------------+ http:/www.gperkins.co.uk/

Mats Helander

unread,
Nov 23, 2001, 5:09:50 AM11/23/01
to

Graham Perkins <gper...@gperkins.co.uk> skrev i
diskussionsgruppsmeddelandet:3BFE366B...@gperkins.co.uk...

> Mats Helander wrote:
>
> > If I get this right, that means that:
> > myInstance.doStuff()
> > is in reality:
> > ClassOfMyInstance.doStuff(this) 'static method
> > where myInstance is passed to the 'this' parameter?
>
> Yes. Just about. That is the effect. But you could not
> simulate objects directly in a modular language with such
> a direct substitution. Between "myInstance.doStuff()" and
> "ClassOfMyInstance.doStuff( myInstance )" there is the
> problem of finding what exactly is the class of myInstance.

Right....Well I guess you'd be able to do it by using a cetral dispatcher
and add some maniac global hash list for associating variables with "made-up
types" (for the dispatcher to use), but hey....I'm glad I don't have to. But
I take your point to be "It's not exactly fair to call
'myInstance.doStuff()' a pure 'syntactig suger' improvement over
'ClassOfMyInstance.doStuff( myInstance )'", which I duely note...

> > Aha! So for a non-overriden inherited method, the virtual method table
> > points to the same address as for the method in the superclass, right?
Thus
> > Scott Ambler's remark earlier that the "delegation" approach will cost
an
> > extra jump for methods?
>
> Yes. With dynamic binding, every function call is a "gosub" to
> an address retrieved from the VMT. Whereas in static binding each
> function call is a gosub to an address known at compile time.
>
> ISE's Eiffel compiler is very good at optimising many apparently
> polymorphic calls into static binding.
>
> The smalltalk approach has to be different since its dynamic
> nature prevents compile-time analysis of static/dynamic binding.
> However, at runtime the various loaders and JIT native coders
> can "corral" lumps of code and optimise it.

How do they do that? Do they guess based on previous uses of the code, and
then discard the guesses if there is unanticipated use? If I get you right,
you're saying that the JIT compilers will "pre-bind" loosely bound types
(basically, guess which VMT to use) in order to gain speed...or did I get it
wrong?

> [ re: runtime editing ]
> > I created a (rather simple) OO system that allowed you to do that. The
> > lesson I learned was to never use something like that again! ;-) No,
> > seriously, it works fine for RAD prototyping, but IMO it's not as useful
for
> > something that you're actually gonna deploy.
>
> I think smalltalkers would disagree!
> For a start, the iterative prototyping approach can be used
> for real development, not just RAD prototyping. Eg, see the
> Objectory methodology. One thing I really like is that it
> is extremely easy to develop deliverable code and test drivers
> in parallel. In particular, we can build an object structure
> to run tests against, and keep testing as we add more methods.
> No need to rebuild the entire target object structure every
> time we edit/add the methods.
>
> And for another, the ability to update a system while it is
> executing is quite an asset in some circumstances.

Well, the OO system is still used by happy customers, and it sure is fun
when some of them (still) call and wants updates that I can do it (add and
modify classes and objects) from home directly in my browser while their
system is still running....so, OK, it's useful. And anyway, I really like
using tools like that to keep a "RAD version" of my project in which I do
most of the experimenting.

Thanks again for all the help!

/Best Regards, Mats Helander

>
> -------------+ http:/www.gperkins.co.uk/


S Perryman

unread,
Nov 18, 2001, 6:20:10 PM11/18/01
to

Robert C. Martin <rmartin @ objectmentor . com> wrote in message
news:uq6ovtskv7bqsqv0c...@4ax.com...

>folks who insist that Circle classes must inherit from Elipse
>classes are confusing geometric shapes with software.

>This is precisely the point of the whole argument. The term ISA can
>be applied to various domains, like mathematics and geometry. There
>are concepts in those domains that can be mapped to software. A
>geometric circle can be mapped to become class Circle in a software
>application. However, the relationships in one domain may not map
>well into the software domain. The ISA relationship between Circle
>and Elipse in the geometry domain does not map well into the software
>domain.

The ISA relationship maps very well indeed to the impl space.

I have no problems doing so, and I have yet to be presented with any
'posers' on the circle/ellipse topic that cannot be easily swept away
with simple and elegant solutions, Or by actually applying the
*fundamentals* of CS + sw eng. However, I have seen people
proclaim things that show a misunderstanding of the fundamentals.


Regards,
Steven Perryman


Dave Harris

unread,
Nov 23, 2001, 9:32:00 AM11/23/01
to
rmartin @ objectmentor . com (Robert C. Martin) wrote (abridged):

> You can increase the accessibility of an element of a derivative; but
> you cannot decrease it. That is, you cannot make an inherited member
> less accessible than it's base.

You can in C++. Eg:

class Base
{
public:
virtual void member();
};

class Derived : public Base
{
private:
virtual void member();
};

void test()
{
Derived d;
// d.member(); // Won't compile.
Base &b = d;
b.member();
}

This compiles. Removing the "virtual" makes no difference. If we uncomment
the commented line, it won't compile because D::member() really is
private.

The next two lines show that, as Graham Perkins says, the protection isn't
reliable as the member is accessable via the base class, without needing
to use a cast or other nasty tricks.

Dave Harris, Nottingham, UK | "Weave a circle round him thrice,
bran...@cix.co.uk | And close your eyes with holy dread,
| For he on honey dew hath fed
http://www.bhresearch.co.uk/ | And drunk the milk of Paradise."

Dave Harris

unread,
Nov 23, 2001, 9:32:00 AM11/23/01
to
ma...@urbantalk.se (Mats Helander) wrote (abridged):

> The basic idea is this: Could you have some sort of "conditional" or
> "dynamic" types?

Yes. The language Cecil has these under the name "predicate type". It has
been discussed here before. I expect a search for those words will turn up
more.

Mats Helander

unread,
Nov 23, 2001, 7:41:38 AM11/23/01
to

Dave Harris <bran...@cix.co.uk> skrev i
diskussionsgruppsmeddelandet:memo.2001112...@brangdon.madasafish.c
om...

> ma...@urbantalk.se (Mats Helander) wrote (abridged):
> > The basic idea is this: Could you have some sort of "conditional" or
> > "dynamic" types?
>
> Yes. The language Cecil has these under the name "predicate type". It has
> been discussed here before. I expect a search for those words will turn up
> more.

So, both "dependent types" (Cayenne) and "predicate types" are used...are
they exactly the same thing?

Thanks for the info!

/Best Regards, Mats Helander

Graham Perkins

unread,
Nov 23, 2001, 9:48:55 AM11/23/01
to
Mats Helander wrote:
> > ISE's Eiffel compiler is very good at optimising many apparently
> > polymorphic calls into static binding.
> >
> > The smalltalk approach has to be different since its dynamic
> > nature prevents compile-time analysis of static/dynamic binding.
> > However, at runtime the various loaders and JIT native coders
> > can "corral" lumps of code and optimise it.
>
> How do they do that?

Sorry, I don't know *how* it is done! Maybe James Robertson or
others could clarify.

All I know is that when issues of efficiency have come up, the
smalltalk systems programmers have argued that their localised
flow analysis at JIT-compile time is pretty good. Obviously it
cannot generate as much efficiency as full static system PLUS
JIT flow-analysis, but most static typed systems don't bother
with a great deal of flow analysis.

-------------+ http:/www.gperkins.co.uk/

James A. Robertson

unread,
Nov 23, 2001, 11:30:39 AM11/23/01
to
Graham Perkins wrote:

> Mats Helander wrote:
>
>>>ISE's Eiffel compiler is very good at optimising many apparently
>>>polymorphic calls into static binding.
>>>
>>>The smalltalk approach has to be different since its dynamic
>>>nature prevents compile-time analysis of static/dynamic binding.
>>>However, at runtime the various loaders and JIT native coders
>>>can "corral" lumps of code and optimise it.
>>>
>>How do they do that?
>>
>
> Sorry, I don't know *how* it is done! Maybe James Robertson or
> others could clarify.


I don't get into that level of detail. However, you can check some of
the back OOPSLA papers - I know that topic has been covered

@objectmentor.com Robert C. Martin

unread,
Nov 23, 2001, 2:47:52 PM11/23/01
to

It must be very very out of date. I remember reading about that rule
in 1991.

@objectmentor.com Robert C. Martin

unread,
Nov 23, 2001, 2:52:40 PM11/23/01
to
On Fri, 23 Nov 2001 14:32 +0000 (GMT Standard Time),
bran...@cix.co.uk (Dave Harris) wrote:

>rmartin @ objectmentor . com (Robert C. Martin) wrote (abridged):
>> You can increase the accessibility of an element of a derivative; but
>> you cannot decrease it. That is, you cannot make an inherited member
>> less accessible than it's base.
>
>You can in C++. Eg:
>
> class Base
> {
> public:
> virtual void member();
> };
>
> class Derived : public Base
> {
> private:
> virtual void member();
> };
>
> void test()
> {
> Derived d;
> // d.member(); // Won't compile.
> Base &b = d;
> b.member();
> }
>
>This compiles. Removing the "virtual" makes no difference. If we uncomment
>the commented line, it won't compile because D::member() really is
>private.
>
>The next two lines show that, as Graham Perkins says, the protection isn't
>reliable as the member is accessable via the base class, without needing
>to use a cast or other nasty tricks.

OK, I see the problem. In C++ you can do this:

class B
{
private:
void f();
};

class D : public B
{
public:
using B::f;
};

This redeclares B::f in D and makes it public. Thus the self-same f
that is private in B can be public in D. C++ does not allow you do
invert this however. You cannot declare B::f public and then
redeclare it in D as private. This is what I thought you were
referring to.

In your example above, Base::member and Derived::member are two
different functions. In C++ one can indeed be public while the other
is private. This has the interesting benefit of *forcing* clients to
polymorphically invoke the functions through the base class.

Martin Fowler

unread,
Nov 23, 2001, 8:25:37 PM11/23/01
to

>So basically your last two examples commit a logical fallacy (I don't know
>the name of it offhand). The problem isn't the concept "is a", but not
>keeping track of what the "is a"'s are referring to.

So we are essentially in agreement. (Although we use a slightly
different way to look at the problem.)

Martin

Thomas Maeder

unread,
Nov 24, 2001, 3:43:31 AM11/24/01
to
Robert C. Martin wrote:

> In C++ you can do this:
>
> class B
> {
> private:
> void f();
> };
>
> class D : public B
> {
> public:
> using B::f;
> };


Can you? Wouldn't f() have to be protected in B?

Dave Harris

unread,
Nov 24, 2001, 11:40:00 AM11/24/01
to
rmartin @ objectmentor . com (Robert C. Martin) wrote (abridged):
> In your example above, Base::member and Derived::member are two
> different functions.

OK... but this matches what Graham Perkins originally wrote:

Moreover, I see you can override any method and
declare different visibility in the derived class.

He's talking about overriding virtual functions, not using-declarations. I
think you mis-understood what he meant.

Dave Harris

unread,
Nov 24, 2001, 11:40:00 AM11/24/01
to
ma...@urbantalk.se (Mats Helander) wrote (abridged):
> > The smalltalk approach has to be different since its dynamic
> > nature prevents compile-time analysis of static/dynamic binding.
> > However, at runtime the various loaders and JIT native coders
> > can "corral" lumps of code and optimise it.
>
> How do they do that? Do they guess based on previous uses of the code,
> and then discard the guesses if there is unanticipated use?

Guessing is good. It's much quicker to verify a guess is correct than to
produce a guaranteed correct answer, so they use caching. Often a single
cached value does well, if each call site gets its own. Sometimes
multi-valued caches do better.

Sometimes we can reuse the result of a guess for several different
message-sends, or hoist it out of inner loops. Then the dispatch cost
becomes a tiny fraction of the total time. This amounts to producing a
"specialised" version of the code.

"Discarding the guess" may just mean updating the cache, or it may mean
regenerating a section of specialised code completely.

For more, start with the implementation papers for Self at:
http://research.sun.com/self/papers/papers.html

Using dynamic approach which can deal gracefully with bad guesses at
run-time, can out-perform approaches which try to deal with all
possibilities at compile-time. The former is "optimistic" and the latter
"pessimistic".

Dave Harris

unread,
Nov 24, 2001, 11:40:00 AM11/24/01
to
ma...@urbantalk.se (Mats Helander) wrote (abridged):
> So, both "dependent types" (Cayenne) and "predicate types" are
> used...are they exactly the same thing?

I don't know. I'd never heard of Cayanne before :-) I will look into it.
The language seems a bit different to Cecil, being a functional language.
Cecil is more of an OO one.

Cecil is at:
http://www.cs.washington.edu/research/projects/cecil/


> Thanks for the info!

Likewise.

Universe

unread,
Nov 24, 2001, 5:59:48 PM11/24/01
to
fow...@acm.org (Martin Fowler) wrote:

Not at all. You are agreeing with his argument you are wrong on the
"is_a" issue

By agreeing with him on this point, whether you realize it or not, you
are validating his whole explicitly Logic form point against your
claim that "is_a" has problems that some times make "is_a" impossible
to implement in software

Shayne Wissler

unread,
Nov 24, 2001, 6:53:01 PM11/24/01
to

"Universe" <univ...@directvinternet.undocom> wrote in message
news:1j800ucg8fp7utpsp...@4ax.com...

> fow...@acm.org (Martin Fowler) wrote:
>
> >
> >>So basically your last two examples commit a logical fallacy (I don't
know
> >>the name of it offhand). The problem isn't the concept "is a", but not
> >>keeping track of what the "is a"'s are referring to.
>
> >So we are essentially in agreement. (Although we use a slightly
> >different way to look at the problem.)
>
> Not at all. You are agreeing with his argument you are wrong on the
> "is_a" issue
>
> By agreeing with him on this point, whether you realize it or not, you
> are validating his whole explicitly Logic form point against your
> claim that "is_a" has problems that some times make "is_a" impossible
> to implement in software

I didn't see him as advocating Bob Martin's point of view. He was just
pointing out that people have been confused over "is a" for a long time, and
not just with software, but with logic in general. My post just took his
examples and analyzed them in order to show precisely what was happening
when "is a" supposedly broke down: in fact, it wasn't the concept breaking
down, but how it was being applied.


Shayne Wissler

Mats Helander

unread,
Nov 24, 2001, 6:34:22 PM11/24/01
to
Thanks for the great explanation and the link!

I wonder if this isn't an area where conditional probabilistics might one
day make a big difference...

/Best Regards, Mats Helander


Dave Harris <bran...@cix.co.uk> skrev i
diskussionsgruppsmeddelandet:memo.2001112...@brangdon.madasafish.c
om...

@objectmentor.com Robert C. Martin

unread,
Nov 24, 2001, 10:42:32 PM11/24/01
to
On Sat, 24 Nov 2001 09:43:31 +0100, Thomas Maeder <mae...@glue.ch>
wrote:

Yes it would.

L. F. Hall

unread,
Nov 27, 2001, 9:13:35 PM11/27/01
to
From: Robert C. Martin <rmartin @ objectmentor . com>
Date: Wed, 21 Nov 2001 00:15:40 -0600
Message-ID: <adhmvt455st1mprpe...@4ax.com>

[snip - see archives, this thread and "Re: On LSP *is_a*,rel P*: ...."]

> I'm having trouble seeing the flaw. The violation in both cases is in
> the Square class. Square is not substitutable for valid clients of
> Rectangle. Both f and g are valid clients of Rectangle that do not
> violate any of Recatangles implied contracts. Neither f nor g know
> anything at all about Square, nor should they. Yet if a Square is
> passed into these functions, in the guise of a Rectangle; confusion
> results. Either the Square is corrupted (in the f case) or the
> client's expectations are violated. It is not g nor f that violate
> the LSP. Those functions don't violate anything at all. It is the
> implementation of Square that violate the LSP.

From your paper http://www.objectmentor.com/publications/lsp.pdf
(quoting Barbara Liskov)

> What is wanted here is something like the following substitution
> property: If for each object o1 of type S there is an object o2 of
> type T such that for all programs P defined in terms of T, the
> behavior of P is unchanged when o1 is substituted for o2 then
> S is a subtype of T.

This statement of LSP cited in your 1996 paper is not violated when
your first Square is passed to f in the guise of a Rectangle. When a
Square is substituted for an equal-sided Rectangle in your f case,
the Square object is changed by f just like the Rectangle would be
changed. Your statement in the paper, "This is a clear violation
of LSP" is inaccurate. This is the flaw. (The behavior of P *is*
unchanged.)

That the Square is corrupted in the f case does not violate LSP,
for the LSP cited does not require that the derived class object be
protected from change. Your design change to prevent corruption
of Square objects leads to the g case, in which "the behavior of
P" is changed and LSP is violated, but that only complicates the
issue by masking the flaw in the development. We are left with
the inaccurate conclusion that

> It is the implementation of Square that violate the LSP.

when the actual problem with the f case is that Square invariants
are violated.

I agree that the screen acres devoted to this issue (or the screen
hectares, if you prefer) are beyond belief, but one must ask why
is this so? My partial answer is that straightforward issues of
design wisdom and professional choice keep running aground
on "isa," which seems so natural but is so controversial.

So what's the big deal? Why have I contributed yet another
episode of "screen acres" to the set? It is because unaffordable
hours have been lost to confusion and to reading, writing and
study on a matter which would have passed into understanding
in little time were it not paradoxical. Perhaps, others also have
been confused. It helped when I understood that the driving
energy in this issue came from preservation of class invariants
(as many posters noted) rather than an inheritance problem due
to violating LSP. "Don't do this at home without a net!" is very
good advice that doesn't challenge intuition if it is tied to class
invariants instead of *is_a* breakdown. Right conclusions are
not enough; right reasons also are important.

Tnx for the moments,
Len

Universe

unread,
Nov 27, 2001, 11:43:21 PM11/27/01
to
"L. F. Hall" <p...@eot.com> wrote:

>From: Robert C. Martin <rmartin @ objectmentor . com>
>Date: Wed, 21 Nov 2001 00:15:40 -0600
>Message-ID: <adhmvt455st1mprpe...@4ax.com>
>
>[snip - see archives, this thread and "Re: On LSP *is_a*,rel P*: ...."]
>
>> I'm having trouble seeing the flaw. The violation in both cases is in
>> the Square class. Square is not substitutable for valid clients of
>> Rectangle. Both f and g are valid clients of Rectangle that do not
>> violate any of Recatangles implied contracts. Neither f nor g know
>> anything at all about Square, nor should they. Yet if a Square is
>> passed into these functions, in the guise of a Rectangle; confusion
>> results.

You are violating hidden invariants in the "is_a" model of the domain
by passing it such a Rectangle.

Your confused results from insistence on using an "is_a" invariance
from one domain in another. When things blow up as a result you then
blame alleged shortcomings in the "is_a" modelling technique.

You are imposing "is_a" expectations from one domain on another.

Stick to the modelling requirements of your domain and "is_a" can be
used fine. No modelling technique in the world can withstand
violations of model premises. Not your imagined premises, but the
real premises you haven't even taken the time to understand.

Elliott

Universe

unread,
Nov 28, 2001, 12:03:46 AM11/28/01
to
Universe <univ...@directvinternet.undocom> wrote:

>"L. F. Hall" <p...@eot.com> wrote:
>
>>From: Robert C. Martin <rmartin @ objectmentor . com>
>>Date: Wed, 21 Nov 2001 00:15:40 -0600
>>Message-ID: <adhmvt455st1mprpe...@4ax.com>
>>
>>[snip - see archives, this thread and "Re: On LSP *is_a*,rel P*: ...."]
>>
>>> I'm having trouble seeing the flaw. The violation in both cases is in
>>> the Square class. Square is not substitutable for valid clients of
>>> Rectangle. Both f and g are valid clients of Rectangle that do not
>>> violate any of Recatangles implied contracts. Neither f nor g know
>>> anything at all about Square, nor should they. Yet if a Square is
>>> passed into these functions, in the guise of a Rectangle; confusion
>>> results.

>You are violating hidden invariants in the "is_a" model of the domain
>by passing it such a Rectangle.
>
>Your confused results from insistence on using an "is_a" invariance
>from one domain in another. When things blow up as a result you then
>blame alleged shortcomings in the "is_a" modelling technique.
>
>You are imposing "is_a" expectations from one domain on another.
>
>Stick to the modelling requirements of your domain and "is_a" can be
>used fine. No modelling technique in the world can withstand
>violations of model premises. Not your imagined premises, but the
>real premises you haven't even taken the time to understand.
>
>Elliott

Additionally Goedel pointed out a while ago that no system is
consistent within itself. No systems is fully self-consistent. We
must go outside of the system to explain certain aspects of the
system. Even with a given set of premises there will be corollaries
of those premises that violate the premises themselves.

Even if you actually did find a real world situation that can't be
modelled in software, which you haven't thus far, that in no way
implies the modelling concepts used in software do not mirror, do not
have a basis in, or do not correspond with processes and things in the
real world.

So better to learn from reality how to model it better than to attempt
to isolate one sphere of the real world - software - from the rest of
it, because the real world is a lot richer and holds much more actual
promise than what the minds of even the best individuals can conceive.

Shayne Wissler

unread,
Nov 28, 2001, 12:26:31 AM11/28/01
to

"Universe" <univ...@directvinternet.undocom> wrote in message
news:stq80u8jtmk7qgiam...@4ax.com...

> Additionally Goedel pointed out a while ago that no system is
> consistent within itself. No systems is fully self-consistent. We
> must go outside of the system to explain certain aspects of the
> system. Even with a given set of premises there will be corollaries
> of those premises that violate the premises themselves.

Godel was talking about *formal* systems, and he didn't say they were "not
self-consistent". If I recall correctly, his point was that no formal system
could be used, by itself, to prove all possible true statements made using
that formal system.

Modern crackpots have applied his statements to humans (e.g., saying that
humans can't prove anything because they can't get outside themselves),
forgetting the fact that his theory doesn't apply to humans, because they
aren't formal systems.


Shayne Wissler

Universe

unread,
Nov 28, 2001, 12:32:05 AM11/28/01
to
"Shayne Wissler" <thal...@yahoo.com> wrote:

>
>"Universe" <univ...@directvinternet.undocom> wrote in message
>news:stq80u8jtmk7qgiam...@4ax.com...
>
>> Additionally Goedel pointed out a while ago that no system is
>> consistent within itself. No systems is fully self-consistent. We
>> must go outside of the system to explain certain aspects of the
>> system. Even with a given set of premises there will be corollaries
>> of those premises that violate the premises themselves.

>Godel was talking about *formal* systems, and he didn't say they were "not
>self-consistent". If I recall correctly, his point was that no formal system
>could be used, by itself, to prove all possible true statements made using
>that formal system.

? The 2 mean, or read, 97% the same. At least to me anyway.

>Modern crackpots have applied his statements to humans (e.g., saying that
>humans can't prove anything because they can't get outside themselves),
>forgetting the fact that his theory doesn't apply to humans, because they
>aren't formal systems.

Yes, I've seen this.

Elliott

Universe

unread,
Nov 28, 2001, 12:38:49 AM11/28/01
to
Universe <univ...@directvinternet.undocom> wrote:


I made the same points below in a letter to the editor in C++ Report
in response to RMartin in '96.

It must have rung true because Doug Schmidt, a RMartin, comrade in
thought, took me threw a ringer of rewriting before he published it.

Elliott
----------------


>You are violating hidden invariants in the "is_a" model of the domain
>by passing it such a Rectangle.
>

>Your confus[ion] results from insistence on using an "is_a" invariance

Universe

unread,
Nov 28, 2001, 1:04:08 AM11/28/01
to
Universe <univ...@directvinternet.undocom> wrote:

>"Shayne Wissler" <thal...@yahoo.com> wrote:

>>Godel...If I recall correctly, his point was that no formal system


>>could be used, by itself, to prove all possible true statements made using
>>that formal system.

>? The 2 mean, or read, 97% the same. At least to me anyway.

>>Modern crackpots have applied his statements to humans (e.g., saying that
>>humans can't prove anything because they can't get outside themselves),
>>forgetting the fact that his theory doesn't apply to humans, because they
>>aren't formal systems.

>Yes, I've seen this.

>Elliott

And by whom? Of course the vocal XP/Agility types. Some of them
periodically drag this Goedel insight and ["Lake of Fire" (or similar
w/ "Fire"), by Escher, Goedel, Bach] to support the false notion that
there is no contextually relative truth.

They twist Goedel's system theory (not sure about the book's theory)
to claim that there is no need, and as RMartin, is currently claiming
it's even deleterious, to model the real world, and use key domain
objects and relationships in the system object model [as reflected in
Unified Process/Objectory/Universe like "Logical Object Design"
(LOD)].

However, I do want to read the book, to be begetter at battling
extreme empiricism, logical positivism, XP/Agility, etc. I've read a
cart of similar though - Ernest Mach, Bishop Berkeley, etc.

Universe

unread,
Nov 28, 2001, 1:44:59 AM11/28/01
to
Universe <univ...@directvinternet.undocom> wrote:

But thanks a bunch Mr. Hall, your prescient remarks rekindled valuable
lines of thought for me on this issue.

Elliott
----------------

Dmitry A. Kazakov

unread,
Nov 28, 2001, 4:30:27 AM11/28/01
to

There is inner and outer substitutablity. The inner substitutability
ensures that an object of a subtype passed as a parameter of the base
type does not break the callee. The outer substitutability ensures
that the callee cannot break the object (and its invariant) and so the
caller.

It is right that Square is inner-substitutable for Rectangle (if there
is no dispatching methods), but it is not outer-substitutable in
in/out (mutable) mode.

The whole sense of LSP is to ensure that all programs written for
Rectangles will work for Squares. This requires *both* kinds of
substitutability.

The actual problem with LSP is that the sentence "all possible
programs <valid> for a type T" presumably identifies the type T [when
<valid> is defined in a more or less useful way]. Which makes LSP
subtypes of T rather useless. As Robert Martin have already pointed,
the notion of subset (and thus is-a) is much weaker than LSP
subtyping. In short is-a is about elements, LSP is about sets [of
elements]. They simply cannot be isomorphic.

>I agree that the screen acres devoted to this issue (or the screen
>hectares, if you prefer) are beyond belief, but one must ask why
>is this so? My partial answer is that straightforward issues of
>design wisdom and professional choice keep running aground
>on "isa," which seems so natural but is so controversial.
>
>So what's the big deal? Why have I contributed yet another
>episode of "screen acres" to the set? It is because unaffordable
>hours have been lost to confusion and to reading, writing and
>study on a matter which would have passed into understanding
>in little time were it not paradoxical. Perhaps, others also have
>been confused. It helped when I understood that the driving
>energy in this issue came from preservation of class invariants
>(as many posters noted) rather than an inheritance problem due
>to violating LSP.

Preserving invariants is not all. An absolute inner substitutablity
can be achived only if a callee has no way to discover a difference
between a Rectangle and a Square. Thus one should get rid of all forms
of indentity [including dispatch]. Which is a bit painful for OO, I
presume.

> "Don't do this at home without a net!" is very
>good advice that doesn't challenge intuition if it is tied to class
>invariants instead of *is_a* breakdown. Right conclusions are
>not enough; right reasons also are important.

Regards,
Dmitry Kazakov

@objectmentor.com Robert C. Martin

unread,
Nov 28, 2001, 10:03:18 AM11/28/01
to
On Wed, 28 Nov 2001 02:13:35 GMT, "L. F. Hall" <p...@eot.com> wrote:

OK, I think I see the miscommunication. You are thinking that
function f corresponds to program P in Liskov's definition. That's
not my intent. Program P is the program as a whole. Function f is
just part of that program. Clearly, the program as a whole is
malfunctioning when you pass a Square instance into function f.


>
>That the Square is corrupted in the f case does not violate LSP,
>for the LSP cited does not require that the derived class object be
>protected from change. Your design change to prevent corruption
>of Square objects leads to the g case, in which "the behavior of
>P" is changed and LSP is violated, but that only complicates the
>issue by masking the flaw in the development. We are left with
>the inaccurate conclusion that
>
>> It is the implementation of Square that violate the LSP.
>
>when the actual problem with the f case is that Square invariants
>are violated.

True, but they are violated by the methods that are inherited from
Rectangle. Square has no ability to hide these methods, and users of
Rectangle are not likely to know that they are dealing with Squares.

Clearly the problem that both f and g are having can be eliminated by
a different implementation of Square, in which Square does not inherit
from Rectangle. In the end, it is this inheritance that is causing
the trouble.

The real problem, in both the f and g case, is a violation of the
principles of design by contract. According to those principles, the
postconditions of a derived method must not be incompatible with the
post conditions of the overridden base method. However, in the
Square/Rectangle problem the necessary postconditions of
Square::SetWidth() *are* incompatible with the necessary
postconditions of Rectangle::SetWidth. Function f and g are just
symptoms of that incompatibility. (This argument is made starting on
page 6 of the paper.)

>So what's the big deal? Why have I contributed yet another
>episode of "screen acres" to the set? It is because unaffordable
>hours have been lost to confusion and to reading, writing and
>study on a matter which would have passed into understanding
>in little time were it not paradoxical. Perhaps, others also have
>been confused. It helped when I understood that the driving
>energy in this issue came from preservation of class invariants
>(as many posters noted) rather than an inheritance problem due
>to violating LSP. "Don't do this at home without a net!" is very
>good advice that doesn't challenge intuition if it is tied to class
>invariants instead of *is_a* breakdown. Right conclusions are
>not enough; right reasons also are important.

It seems to me that there is a similarity in our two arguments. You
are claiming that the problem has to do with invariants, and I'm
claiming that it has to do with postconditions.

The religious use of ISA is one of my pet peeves. People have been
trained that if you can say X ISA Y then you can use inheritance
between the representative classes. This is not always the case.

David Crocker

unread,
Nov 28, 2001, 12:55:58 PM11/28/01
to
I would put it another way. The method SetWidth has a precondition, which
may be expressed as the result of calling CanSetWidth. CanSetWidth is itself
a virtual function, which returns true for a Rectangle, but for a square
returns true only if the width you are trying to set is the same as the
current one.

Naturally you would not want code to be generated for CanSetWidth (unless
you are checking contracts at runtime). In Verified DBC (see
www.eschertech.com) it is called a "ghost function", i.e. a function whose
purpose is solely to allow contracts, invariants, assertions etc. to be
correctly stated, and for which code should not normally be generated.

Dave

"Robert C. Martin" <rmartin @ objectmentor . com> wrote in message
news:acu90uci8hcg05f3v...@4ax.com...

@objectmentor.com Robert C. Martin

unread,
Nov 29, 2001, 12:28:04 AM11/29/01
to
On Wed, 28 Nov 2001 17:55:58 -0000, "David Crocker"
<dcro...@imsltd.com> wrote:

>I would put it another way. The method SetWidth has a precondition, which
>may be expressed as the result of calling CanSetWidth. CanSetWidth is itself
>a virtual function, which returns true for a Rectangle, but for a square
>returns true only if the width you are trying to set is the same as the
>current one.

The original scenario had class Rectangle being created a year before
the need for class Square was identified. I don't think it's
realistic to suppose that the developers of class Rectangle would have
the precience to put the 'CanSetWidth' method in class Rectangle.

S Perryman

unread,
Nov 29, 2001, 7:32:13 AM11/29/01
to

Robert C. Martin <rmartin @ objectmentor . com> wrote in message
news:acu90uci8hcg05f3v...@4ax.com...

S Perryman

unread,
Nov 29, 2001, 7:33:46 AM11/29/01
to
Robert C. Martin <rmartin @ objectmentor . com> wrote in message
news:acu90uci8hcg05f3v...@4ax.com...
> On Wed, 28 Nov 2001 02:13:35 GMT, "L. F. Hall" <p...@eot.com> wrote:

Having monitored this thread, and knowing of Robert Martins' comments
wrt the LSP from other debates in the past, I decided to read his
paper. This is what I found ...

Looking at functions "f" and "g" (in the sections "Square and
Rectangle, a More Subtle Violation" and "The Real Problem" ) , there
is LSP violation. And there is no LSP violation.

How so ??

The reason for the above is because a violation can only occur if
there is a *specification* to validate against. For both examples,
there are none. Therefore how can one argue as to whether the LSP
is being violated or not ??

Thus, the question "Was the programmer who wrote that function
justified in assuming ..." is answered as : NO.

Without a specification of *any* form, a developer, no matter how
'trivial' a supplied component appears to be, cannot *assume* anything
about that component that is *not* written, nor is not *derivable*
from what is written (formal proofs etc) .

It is also noted that nowhere in the paper does Robert Martin actually
seem to grasp this fundamental reality. The best we got was :

"Moreover, it can be very helpful to document these preconditions and
postconditions in the comments for each method."

How nice. It can be helpful.
It should be *mandatory* to document them. CS 101 anyone ??


- Inability to apply Design by Contract

Reading the section "Design by Contract" , the following statements
are made :

"Clearly, the postcondition of Square::SetWidth(double w) is weaker
than the postcondition of Rectangle::SetWidth(double w) above, since
it does not conform to the base class clause "(itsHeight == old.
itsHeight)". Thus, Square::SetWidth(double w) violates the contract
of the base class."


It took only a few seconds for me to prove that the postcondition of
Square::setWidth is in fact *stronger* than that of Rectangle.
Therefore Robert Martins' argument is rendered incorrect, and Square
is in fact LSP-conformant with Rectangle based on his argument.

However, based on a *correct* application of Design by Contract to the
Rectangle/Square example, I was able to prove that Square does violate
Rectangle::setWidth. But the reason for the violation was quite
different to the (failed) one given by Robert Martin.


Regards,
Steven Perryman


L. F. Hall

unread,
Nov 29, 2001, 3:06:38 PM11/29/01
to
From: Robert C. Martin <rmartin @ objectmentor . com>
Date: Wed, 28 Nov 2001 09:03:18 -0600
Message-ID: <acu90uci8hcg05f3v...@4ax.com>

> On Wed, 28 Nov 2001 02:13:35 GMT, "L. F. Hall" <p...@eot.com> wrote:

> >From: Robert C. Martin <rmartin @ objectmentor . com>
> >Date: Wed, 21 Nov 2001 00:15:40 -0600
> >

Yes, and I think g corresponds to program P in its section.

> That's
> not my intent. Program P is the program as a whole. Function f is
> just part of that program.

This appears to go beyond Barbara Liskov's statement of LSP. I am
unable to see in her words that program P is the program_as_a_
whole.

> Clearly, the program as a whole is
> malfunctioning when you pass a Square instance into function f.
>

IMO, the determination of malfunction is based on information
beyond LSP, namely that we know what "square" means and we
don't want the program to elongate one by surprise.

My effort to look into Barbara Liskov's papers several months ago
in order to understand her intent ran into several blocks and I
have had to depend on the quoted statement. Has she addressed
what P is in a way we can resolve this difference of interpretation?

Also, having reviewed this thread and additional screen acres on
the subject, including FAQ, and having run into it in several texts
(including one in which problems caused by the implicit assumption
"has wing - can fly" was the focus of cautions against public
inheritance), I understand that the issue is rich in answers and
somewhat like a battlefield in science wars. As a student, and in
compassion for imagined confusion of others, my simple hope is
that we may reduce confusion by separating discussion of LSP
and valid *is_a* cases from the design considerations we need
to prevent surprises.

[snip]

> It seems to me that there is a similarity in our two arguments. You
> are claiming that the problem has to do with invariants, and I'm
> claiming that it has to do with postconditions.

My focus on invariants was learned in these discussions, and I have
learned other valuable points as well, but I wished to be succinct in
seeking a footing of agreement on which to build. We agree that it
is not good for a Square to be elongated by surprise, and that there
are design constraints that can be used to prevent writing classes
in which this might happen.

Unfortunately, as noted above, IMO your paper uses LSP beyond
Barbara Liskov's rigorous statement and it challenges too strongly
our intuition with respect to inheritance. Perhaps, we need a fresh
paper for students that would acknowledge that Square *is_a*
Rectangle can be implemented in well formed code, and then
would detail the other design considerations that are needed for
well formed programs that will meet the expectations of experts.
The subject keeps coming up as a controversy: maybe this
approach would let it rest in well defined peace. (Hope is good,
too.)

> The religious use of ISA is one of my pet peeves. People have been
> trained that if you can say X ISA Y then you can use inheritance
> between the representative classes. This is not always the case.

I read you loud and clear. Unfortunately, the claim often seems to be
that it is NEVER the case, and that triggers challenge. Your position as
author of the paper frequently quoted in cautions about *is_a* and
inheritance is unique in its opportunity to clear the air for us all.

@objectmentor.com Robert C. Martin

unread,
Nov 29, 2001, 4:41:21 PM11/29/01
to
On Thu, 29 Nov 2001 12:33:46 -0000, "S Perryman" <q...@deja.com> wrote:

>Without a specification of *any* form, a developer, no matter how
>'trivial' a supplied component appears to be, cannot *assume* anything
>about that component that is *not* written, nor is not *derivable*
>from what is written (formal proofs etc) .

Life is full of implied contracts. In the case of a class named
Rectangle, there is an implied contract. Most reasonable people would
assume that if you invoke SetWidth on an instance of the Rectangle
class, it will have no effect upon the height.

Would it be better to clearly state the contract? Yes, and No. It
would certainly remove any possible ambiguity, and that would be good.
However if we must document absolutely everything before we do
anything, we'll never get anything done.

Do you really want to read the following on every method of every
class?

Rectangle::SetWidth:
//The callers of Rectangle should note that
//this function does not change the height,
//or the topLeft point.

>Reading the section "Design by Contract" , the following statements
>are made :
>
>"Clearly, the postcondition of Square::SetWidth(double w) is weaker
>than the postcondition of Rectangle::SetWidth(double w) above, since
>it does not conform to the base class clause "(itsHeight == old.
>itsHeight)". Thus, Square::SetWidth(double w) violates the contract
>of the base class."

>It took only a few seconds for me to prove that the postcondition of
>Square::setWidth is in fact *stronger* than that of Rectangle.

The term "weak" comes from DBC. Meyer says that postconditions of
derivatives cannot be weaker then those of their base. Clearly this
is true. If a derivative softened a postcondition that a user of the
base expected, then that user would be confused.

In our case, the Square::SetWidth function has weakened the
postcondition of Rectangle that the Height should be unchanged. In
Square, the height *is* changed. Thus, the postcondition with regard
to height is weaker in Square than in Rectangle.

However, the term "weak" is a strange term to use. Viewed outside of
DBC, the postconditions of the two classes have equal strength. Both
impose certain values on both the height and width. Neither allows
either variable more freedom than the other. It is only when looking
down the inheritance hierarchy, in the context of the rules of DBC,
that the term "weakness" makes any sense in this example.

@objectmentor.com Robert C. Martin

unread,
Nov 29, 2001, 4:46:48 PM11/29/01
to
On Thu, 29 Nov 2001 20:06:38 GMT, "L. F. Hall" <p...@eot.com> wrote:

>> The religious use of ISA is one of my pet peeves. People have been
>> trained that if you can say X ISA Y then you can use inheritance
>> between the representative classes. This is not always the case.
>
>I read you loud and clear. Unfortunately, the claim often seems to be
>that it is NEVER the case, and that triggers challenge. Your position as
>author of the paper frequently quoted in cautions about *is_a* and
>inheritance is unique in its opportunity to clear the air for us all.

It would be foolish to assert that ISA and inheritances are NEVER
coincident. It is equally foolish to assert that they are ALWAYS
coincident.

IMO the use of the term ISA as justification for inheritance is
faulty, and I'd like to see software developers be more careful.

Universe

unread,
Nov 29, 2001, 11:30:15 PM11/29/01
to
"L. F. Hall" <p...@eot.com> wrote:

>From: Robert C. Martin <rmartin @ objectmentor . com>
>>

>> It seems to me that there is a similarity in our two arguments. You
>> are claiming that the problem has to do with invariants, and I'm
>> claiming that it has to do with postconditions.

>My focus on invariants was learned in these discussions, and I have
>learned other valuable points as well, but I wished to be succinct in
>seeking a footing of agreement on which to build. We agree that it
>is not good for a Square to be elongated by surprise, and that there
>are design constraints that can be used to prevent writing classes
>in which this might happen.

Looking at this as "post-condition" implies to me that "pre-condition"
considerations are being approached as ancillary to "post-condition"
considerations. And I think looking at RMartin's argument as whole on
this, it should be clear that he indeed is primarily "back-handing"
"pre-conditions". And that points to the source, or an indication of
the source, of his error on the "is_a" matter.

The reason I think RMartin is concerned with "post" rather than "pre"
conditions is that he is more concerned about applying what he deems
to be proper coding practices above domain semantics. Given his well
known "there is no OOA", his denial that analysis is an integral part
of software engineering or the software engineering team, it only
makes sense that he places coding issues above domain analysis issues.

One of the problems with this is that he is applying coding principles
in the abstract. That is, he is ignoring the overall development
context which is primarily guided by analysis issues, like project
motivation, project scope, key project use cases, domain semantics and
vocabulary, etc.

So rather than leading development including coding issues by analysis
issues, he leads with coding issues. Because his coding is not
integrally tied into and led by analysis, he is in effect considering
coding issues in the abstract. That, as opposed to properly placing
in, and leading coding by, the concrete context of project analysis.

Because this is the case, rather than be concerned with
"pre-conditions", he is only really concerned with "post-conditions".
Correctly formulated "pre-conditions" are rooted in overall project
analysis, and this tends to be fairly obvious. Since RMartin cuts off
analysis from development, he cuts off "pre-conditions" from
consideration.

But the fact of the matter is that correctly formulated
"post-conditions" should _also_ be planted firmly in and vigorously
stem from project analysis viewed as a whole. So really his voiced
concern about "post" over "pre" conditions is not an excuse at all for
his abstract handling of "is_a" and LSP in coding.

"Is_a" and LSP properly engaged must take their direction from project
analysis domain, goal, and scoping issues considered as a whole.
Anything less is hackery, plain and simple.

David Crocker

unread,
Nov 30, 2001, 4:49:44 AM11/30/01
to
OK, fair enough, I missed the start of this thread so I didn't know the
original scenario.

Maybe then the real lesson is that it isn't always possible to extend a
class hierarchy in what seems a logical way without changing the contracts
in the base class?
--
David Crocker, Escher Technologies Ltd. www.eschertech.com


"Robert C. Martin" <rmartin @ objectmentor . com> wrote in message

news:oohb0u03n1gq1huqp...@4ax.com...

Universe

unread,
Nov 30, 2001, 4:20:21 PM11/30/01
to
David Crocker <dcro...@imsltd.com> wrote:
> OK, fair enough, I missed the start of this thread so I didn't know the
> original scenario.
>
> Maybe then the real lesson is that it isn't always possible to extend a
> class hierarchy in what seems a logical way without changing the contracts
> in the base class?

One can validly and in given the context, most aptly do that.

However, the real deal is that the _manufactured_ "dilemma" has been
tactically been effectively solved by MHelander and RCauvin in earlier
posts. For RCauvin, going back several years. And for the
proper strategic perspective, see the last 2 of 3 of my followups.

Elliott
--
http://www.radix.net/~universe ~*~ Enjoy! ~*~
Hail OO Modelling! * Hail the Wireless Web!

@Elliott 2001 my comments ~ newsgroups+bitnet OK

Universe

unread,
Nov 30, 2001, 8:02:13 PM11/30/01
to

>>>>ISE's Eiffel compiler is very good at optimising many apparently
>>>>polymorphic calls into static binding.

Ditto, C++.

Elliott

Universe

unread,
Nov 30, 2001, 8:12:55 PM11/30/01
to
Universe <univ...@radix.undonet> wrote:

>However, the real deal is that the _manufactured_ "dilemma" [as to >{Square/Rectangle|Circle/Ellipse|Etc./Etc.}, "is_a", LSP, and OO] has been
>tactically been [and] effectively solved by RCauvin and MHelander in earlier


>posts. For RCauvin, going back several years.

>And for the
>proper strategic perspective, see the last 2 of 3 of my followups.

Also see, LHall, SPerryman, and SWissler, in this thread, as well, for
correct strategic perspective.

Elliott
--
http://www.radix.net/~universe ~*~ Enjoy! ~*~
Hail OO Modelling! * Hail the Wireless Web!

@Elliott 2001 my comments ~ newsgroups+bitnet quote ok

L. F. Hall

unread,
Dec 1, 2001, 10:44:09 AM12/1/01
to
From: Robert C. Martin <rmartin @ objectmentor . com>
Date: Thu, 29 Nov 2001 15:46:48 -0600
Message-ID: <svad0ug1dt8rdn9r4...@4ax.com>

>On Thu, 29 Nov 2001 20:06:38 GMT, "L. F. Hall" <p...@eot.com> wrote:

>>> The religious use of ISA is one of my pet peeves. People have been
>>> trained that if you can say X ISA Y then you can use inheritance
>>> between the representative classes. This is not always the case.
>>
>>I read you loud and clear. Unfortunately, the claim often seems to be
>>that it is NEVER the case, and that triggers challenge. Your position as
>>author of the paper frequently quoted in cautions about *is_a* and
>>inheritance is unique in its opportunity to clear the air for us all.

>It would be foolish to assert that ISA and inheritances are NEVER
>coincident. It is equally foolish to assert that they are ALWAYS
>coincident.

>IMO the use of the term ISA as justification for inheritance is
>faulty, and I'd like to see software developers be more careful.

Thank you for so objectively helping me to specify the flaw I saw in
your paper and that I think should be corrected in the literature. It
is a matter of opinion whether students would benefit, but IMO there
is more here than a typo to be read around. In any case, your help
and the help of many others has helped me to understand. Thanks.

L. F. Hall

unread,
Dec 1, 2001, 10:44:33 AM12/1/01
to
From: Universe <univ...@directvinternet.undocom>
Message-ID: <clu80us7gaqn1egu4...@4ax.com>

>Universe <univ...@directvinternet.undocom> wrote:
>
>>"Shayne Wissler" <thal...@yahoo.com> wrote:
>
>>>Godel...If I recall correctly, his point was that no formal system
>>>could be used, by itself, to prove all possible true statements made
>>>using that formal system.
>
>>? The 2 mean, or read, 97% the same. At least to me anyway.
>

Ahh, but they are significantly different, as you will find when you look
into Goedel's work as you propose to do. The issue is not just about
formal systems, although formal systems are a better test of the ideas
than informal systems could be. The issue is whether a self-consistent
system can be complete. To meet definitions and purposes of this
approach to comprehending the universe, it was hoped an axiom
based system in mathematics or logic could be complete. Goedel
proved it could not be: he proved that a self-consistent statement
could be made that could not be proved within the system (a
question could be asked that could not be answered within the
system).

Now remember, that was done about the same time that anti-matter
was found in theory by Dirac and later in fact by Anderson. We had
been living for a couple millenia with the idea that geometry was the
perfect science based on axioms and rigorous proof. We had even
survived the extension of geometry to curved systems when the
parallel postulate was set aside and consistent geometries were still
possible in negatively and positively curved spaces. Then Planck used
quanta of action (action, *not energy*) to solve the black-body emission
problem, that is, at a very fundamental level the universe is chunky.
Einstein used the same quanta for photoelectric effects. He further
proposed relativity of space and time and was confirmed by experiment.
All our anchor points were adrift - but we hoped for self-consistent,
complete formal systems to attach us to something in the universe
through math and logic - oops.

>>>Modern crackpots have applied his statements to humans (e.g., saying that
>>>humans can't prove anything because they can't get outside themselves),
>>>forgetting the fact that his theory doesn't apply to humans, because they
>>>aren't formal systems.
>
>>Yes, I've seen this.

But it does apply to proof. Goedel's Theorem does not cause the character
of life in the universe, it merely presents one aspect of it precisely.
Should
humans escape its consequences through a loophole about formality, the
universe will also be found on the other side of the hole.

>>Elliott
>
>And by whom? Of course the vocal XP/Agility types. Some of them
>periodically drag this Goedel insight and ["Lake of Fire" (or similar
>w/ "Fire"), by Escher, Goedel, Bach] to support the false notion that
>there is no contextually relative truth.
>
>They twist Goedel's system theory (not sure about the book's theory)
>to claim that there is no need, and as RMartin, is currently claiming
>it's even deleterious, to model the real world, and use key domain
>objects and relationships in the system object model [as reflected in
>Unified Process/Objectory/Universe like "Logical Object Design"
>(LOD)].

I have not studied the details of the various schools of programming
to the same degree as other science wars over the years, but I
assure you that Shakespeare was right: "Roses have thorns, and
silver fountains mud . . ." As long as there is money available to be
*earned* by effort and methods are available to perform the work to
earn the money, various groups will struggle for "market share" by
many means. "So, Galileo, how did you like house arrest?" Goedel's
Theorem applies here, too, for the claims do not prove.

>However, I do want to read the book, to be begetter at battling
>extreme empiricism, logical positivism, XP/Agility, etc. I've read a
>cart of similar though - Ernest Mach, Bishop Berkeley, etc.
>
>Elliott

If I understand your communications as a larger work, it seems to
me that you are fighting against the crushing of ideas you affirm
rather than fighting to crush all other ideas. Reading Goedel to
enrich your own knowledge might be a better course. BTW,
philosophy illustrates an object oriented quality of life. Classes
are formed in meaning space, instantiated and lived by persons,
and always found to need refactoring by following generations.
One is certain of change.

Incidentally, I understand Robert Martin's struggle against the abuses
of ISA. My point is not that he is wrong about caution, but that one
point in his presentation is in error through excess and that error has
been amplified in other presentations to the detriment of learning an
important aspect of the C++ language. Geometry and C++ are
quite different here, for in geometry we say an elongated square has
become a rectangle, but in C++ our named Square object is no
longer a Square. This is a difference worth fanfare, but one prefers
harmony in the notes of the fanfare chord.

Universe

unread,
Dec 1, 2001, 1:10:55 PM12/1/01
to
"L. F. Hall" <p...@eot.com> wrote:

>From: Universe <univ...@directvinternet.undocom>
>Message-ID: <clu80us7gaqn1egu4...@4ax.com>
>
>>Universe <univ...@directvinternet.undocom> wrote:
>>
>>>"Shayne Wissler" <thal...@yahoo.com> wrote:
>>
>>>>Godel...If I recall correctly, his point was that no formal system
>>>>could be used, by itself, to prove all possible true statements made
>>>>using that formal system.
>>
>>>? The 2 mean, or read, 97% the same. At least to me anyway.
>>
>Ahh, but they are significantly different, as you will find when you look
>into Goedel's work as you propose to do. The issue is not just about
>formal systems, although formal systems are a better test of the ideas
>than informal systems could be. The issue is whether a self-consistent
>system can be complete.

Well why didn't you quote me on Goedel where I said precisely that?
Golly guy. {- : I saaaaiiidddd:

>>Additionally Goedel pointed out a while ago that no system is consistent within itself. No systems is >>fully self-consistent. We must go outside of the system to explain certain aspects of the system. >>Even >with a given set of premises there will be corollaries of those premises that violate the >>premises >themselves.
>>

>>Even if you actually did find a real world situation that can't be modelled in software, which you >>haven't thus far, that in no way implies the modelling concepts used in software do not mirror, do not >>have a basis in, or do not correspond with processes and things in the real world.

Elliott

Sjwissler

unread,
Dec 1, 2001, 4:53:19 PM12/1/01
to

>>>>Modern crackpots have applied his statements to humans (e.g., saying that
>>>>humans can't prove anything because they can't get outside themselves),
>>>>forgetting the fact that his theory doesn't apply to humans, because they
>>>>aren't formal systems.
>>
>>>Yes, I've seen this.
>
>But it does apply to proof.

Prove it. I am serious.

If you think Godel's theorem applies to humans, then it applies to itself, and
is thereby invalidated.


Shayne Wissler

Michael Naunton

unread,
Dec 1, 2001, 6:28:09 PM12/1/01
to
On Sat, 01 Dec 2001 13:10:55 -0500, Universe wrote:
>"L. F. Hall" <p...@eot.com> wrote:
>
>>From: Universe <univ...@directvinternet.undocom>
>>Message-ID: <clu80us7gaqn1egu4...@4ax.com>
>>
>>>Universe <univ...@directvinternet.undocom> wrote:
>>>
>>>>"Shayne Wissler" <thal...@yahoo.com> wrote:
>>>
>>>>>Godel...If I recall correctly, his point was that no formal system
>>>>>could be used, by itself, to prove all possible true statements made
>>>>>using that formal system.
>>>
>>>>? The 2 mean, or read, 97% the same. At least to me anyway.
>>>
>>Ahh, but they are significantly different, as you will find when you look
>>into Goedel's work as you propose to do. The issue is not just about
>>formal systems, although formal systems are a better test of the ideas
>>than informal systems could be. The issue is whether a self-consistent
>>system can be complete.
>
>Well why didn't you quote me on Goedel where I said precisely that?
>Golly guy. {- : I saaaaiiidddd:
>
>>>Additionally Goedel pointed out a while ago that no system is consistent within itself.

This is not right...

Here is a system consistent within itself:

1) All axioms in this system are consistent.

> No systems is fully self-consistent. We must go outside of the system to explain certain aspects
> of the system.

Goedel was not talking about explanations of systems. He was speaking of the
impossibility of completeness in sufficiently powerful consistent systems.

> Even with a given set of premises there will be corollaries of those
> premises that violate the premises themselves."

No, that is an inconsistent system, they are uninteresting, and Goedel
doesn't bother to deal with them.

Regards,
Michael

Universe

unread,
Dec 1, 2001, 9:20:29 PM12/1/01
to
m...@mmn.bellatlantic.net (Michael Naunton) wrote:


[A 3rd party description of Godel's theory is excerpted below.]

>>> Universe wrote:
>>>
>>>No system is fully self-consistent. We must go outside of the
>>>system to explain certain aspects of the system. Even with


>>>a given set of premises there will be corollaries of those
>>>premises that violate the premises themselves.

>This is not right...


>
>Here is a system consistent within itself:
>
>1) All axioms in this system are consistent.

The grammatical structure of the sentence is a system.

A system is where things work together for a common purpose.

In addition to that, I see the content of the sentence. The content
is an assertion which incorrectly refers to itself as a system. I'm
open to change.

>Goedel was not talking about explanations of systems. He was speaking of the
>impossibility of completeness in sufficiently powerful consistent systems.

Please, what do you mean by "the impossibility of completeness"?

>>>No system is fully self-consistent. We must go outside of the


>>>system to explain certain aspects of the system.

>No, that is an inconsistent system, they are uninteresting, and Goedel

>doesn't bother to deal with them.

"This proof states that the propositions on which the mathematical
system is in part based are unprovable because it is possible, in any
logical system using symbols, to construct an axiom that is neither
provable nor disprovable within the same system. To prove the
self-consistency of the system, methods of proof from outside the
system are required." [1931] (Encarta)

So, I was correct:

It is loading more messages.
0 new messages