comp.lang.ada
 help / color / mirror / Atom feed
From: mheaney@ni.net (Matthew Heaney)
Subject: Re: OOP & Packages in Ada
Date: 1998/02/01
Date: 1998-02-01T00:00:00+00:00	[thread overview]
Message-ID: <mheaney-ya023680000102981349070001@news.ni.net> (raw)
In-Reply-To: 6b1atp$ngp$1@Masala.CC.UH.EDU


In article <6b1atp$ngp$1@Masala.CC.UH.EDU>, wanker@exploited.barmy.army wrote:


>Well, I'm thinking along somewhat different lines.  Rather than
>creating an "improvement" over a parent, we are simply making
>a new type.  For example, let's use the cliched example of a
>biological organism:
>
>Let's assume the parent package/object has the following type:
>        Mammal
>
>And the methods:
>        Eat
>        Sleep
>        Breed
>
>Now let's say we declare a child with the following type:
>        Dog
>
>And the method:
>        Bark
>        
>Plus, the Dog, being a type of Mammal also uses the method Eat, 
>Sleep, and Breed.
>
>Now, in this case we want the Eat, Sleep, and Breed methods
>to appear to be part of the Dogs package, because otherwise
>the users of our package would have to know our inheritance
>hierarchy, and also what methods are over-ridden and
>what aren't.  That's too much to have the user worry about,
>and to me seems to hurt the abstraction.

If you want just the "primitive" operations of the type to be directly
visible to clients of the child package, then the answer is, yes, they are
already directly visible.  This sort of thing was already true in Ada 83:
derivation from another type makes all the "primitive" operations of the
parent type implicitly declared at the point of declaration of the derived
type.

That means Eat, Sleep, and Breed are directly visible in the Dog package. 
To call the Eat operation of Dog, the client need only refer to the Dog
package, not the parent package (containing type Mammal).

>I mean to the user, A dog can eat, sleep, and breed as well
>as bark, so it makes perfect sense to have these guys as
>part of the dog package.

They are.

>I guess it's debatable as to whether or not it's desirable
>to have people know that a Dog is derived from Mammal, but
>I don't feel it necessary.

Well then, the use of inheritence is debatable.  The only reason to use
inheritence at all is because you want to enable polymorphic behavior.   If
you never manipulate objects of type Mammal'Class, then why bother
publically deriving from Mammal?  Better is to create a new root type
(here, Dog), and then privately inherit (if necessary) from Mammal.  To do
otherwise is to create unnecessary coupling.

>Furthermore, the situation gets
>really hideous if we have a pretty hefty inheritance chain
>like:
>
>
>Object (Appearance)
>   Organism (Reproduction)
>      Animal (Locomotion)
>         Mammal (Fur_Thickness)
>            Dog (Bark)
>              Collie (Grooming)
>
>
>Where Object has a method Appearance, and Organism is derived
>from object and it has a method Reproduction, and Animal is derived
>from Organism, etc...

You should never have deep inheritence hierarchies in Ada.  If you do, then
you are doing something wrong.

Here's why.  Ada is not a pure object-oriented language.  It was made for
systems programming, specifically designed to implement systems that have
high reliability requirements.  In such systems, only minimal use (if any)
of heap is allowed.  That is why Ada (and C++) has value semantics by
default.

Other languages, say Java or Eiffel, have reference semantics by default. 
Every Dog object goes on the heap.  In fact every object (the exceptions
are "expanded" objects in Eiffel) goes on the heap, and gets automatically
garbage collected.  This ubiquitous use of the heap is fine, but makes
those languages unsuitable for the class of systems for which Ada was
designed.

But this seemingly innocuous decision to make objects have value semantics
has over-arching consequences for design of software systems in Ada (and
C++).  When I declare an object like this

declare
   My_Dog : Collie;
begin

the compiler has to know how much space to allocate for My_Dog at compile
time.  This makes this module *very* sensitive to changes in ancestor
types.  Every time you touch an ancestor package, the compiler is going to
have to recompile *all* the packages containing the declarations of types
in the Collie hierarchy.

Pure object oriented languages don't have this problem, because the
representation of all objects is the same: it's just a pointer, whose size
is known statically.  That's why the style of type design in pure object
oriented languages favors deep hierarchies (as a reuse mechanism), because
there's essentially no compilation penalty.

But we don't have this luxury in Ada systems.  Any change near the root of
a hierarchy is going to have a potentially massive ripple-effect, because
the compiler has to adjust the size of all statically declared objects of
any descendent type.

Sadly, many Ada (and C++) programmers haven't caught on to this idea.  They
create deep hierarchies because "that's how you do it in Eiffel or
Smalltalk, you know, in a pure object oriented language," but then they
have to recompile the universe every time they make a change.  Worse, they
turn around and blame Ada, and say "Ada compiles are slow."  This isn't an
Ada problem, it's a programmer problem.

That is why I admonish you to create hierarchies that are broad and
shallow, and avoid hierarchies that are deep and narrow.  If you want
reuse, don't use inheritence to effect it, use aggregation (or possibly
private inheritence).  Use public inheritence because you want polymorphic
behavior, because you want to allow different representations for a
classwide object.

I will say it again: do not create deep inheritence hierarchies in Ada.  If
you do, you're not thinking in Ada, and you're doing something very very
wrong.

--------------------------------------------------------------------
Matthew Heaney
Software Development Consultant
<mailto:matthew_heaney@acm.org>
(818) 985-1271




  reply	other threads:[~1998-02-01  0:00 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
1998-01-30  0:00 OOP & Packages in Ada wanker
1998-01-31  0:00 ` Mats Weber
1998-01-31  0:00   ` Nick Roberts
1998-01-31  0:00 ` Matthew Heaney
1998-02-01  0:00   ` wanker
1998-02-01  0:00     ` Matthew Heaney [this message]
1998-02-01  0:00     ` Tom Moran
1998-02-02  0:00     ` Jon S Anthony
1998-02-02  0:00     ` Anonymous
1998-02-03  0:00     ` John English
1998-02-04  0:00   ` Don Harrison
1998-02-04  0:00     ` Matthew Heaney
1998-02-05  0:00       ` Don Harrison
1998-02-06  0:00         ` Bob Collins
replies disabled

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox