comp.lang.ada
 help / color / mirror / Atom feed
* OOP & Packages in Ada
@ 1998-01-30  0:00 wanker
  1998-01-31  0:00 ` Matthew Heaney
  1998-01-31  0:00 ` Mats Weber
  0 siblings, 2 replies; 14+ messages in thread
From: wanker @ 1998-01-30  0:00 UTC (permalink / raw)




Hey all,

I've got a question for you.  Assuming we have two packages,
say Parents and Children, and Children contains a type,
Child, that is inherited from a type in Parents (Parents.Parent),
is there a way to easily make all the methods of Parents.Parent
available to Child, so that just with'ing the Children package will
make these methods available?  Wrapper functions/procedures
or renaming might do this, but is there an easier way?

Here is an example of what I'm talking about:

[Possibly incorrect Ada source follows, but you get the picture]

In package Parents, there exists the following declarations:

type Parent is tagged 
    record
	...
    end record;

function  X (P : in Parent'Class) returns Integer;
procedure Y (P : in out Parent'Class);
procedure Z (P : out Parent'Class);


And in package Children there exist the following:

type Child is new Parents.Parent with
   record
	...
   end record;


Now let's say we have a main program that withs both of
these packages, so we have something like:

procedure Main is
    P : Parents.Parent;
    C : Children.Child;
begin
   Parents.X (P);
   Parents.X (C);
end Main;

Now, one problem with this code, is that the user seems to have
to know that the method X for C is located in an entirely
different package.  Is there a way to have the package
Children inherit the methods of its parents and make them
visible so they act like it's own?

In other words, is there a way that we can easily make it
so that we can say:
	Children.X (C);

Instead of:
	Parents.X (C);

Without having to do stuff like renaming every function inside
the child?

Thanks





^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: OOP & Packages in Ada
  1998-01-30  0:00 OOP & Packages in Ada wanker
  1998-01-31  0:00 ` Matthew Heaney
@ 1998-01-31  0:00 ` Mats Weber
  1998-01-31  0:00   ` Nick Roberts
  1 sibling, 1 reply; 14+ messages in thread
From: Mats Weber @ 1998-01-31  0:00 UTC (permalink / raw)



> I've got a question for you.  Assuming we have two packages,
> say Parents and Children, and Children contains a type,
> Child, that is inherited from a type in Parents (Parents.Parent),
> is there a way to easily make all the methods of Parents.Parent
> available to Child, so that just with'ing the Children package will
> make these methods available?  Wrapper functions/procedures
> or renaming might do this, but is there an easier way?

Yes, there is. Do yourself a favor: go to <http://www.adahome.com>, look at
the books section, buy one, spend a day reading it, or look at one of the
tutorials (but don't even try learning from the Ada 95 RM). That way you will
learn how Ada 95's tagged types work and how to use them right. OOP in Ada 95
is a little different form what you have in other OO languages, and it's best
to learn before trying or you (or someone else) will have to maintain code
that is not written right.

> type Parent is tagged
>     record
>         ...
>     end record;
> 
> function  X (P : in Parent'Class) returns Integer;
> procedure Y (P : in out Parent'Class);
> procedure Z (P : out Parent'Class);

These are class-wide operations. It's probably not what you want.

Sorry for being so paternalistic :-)




^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: OOP & Packages in Ada
  1998-01-31  0:00 ` Mats Weber
@ 1998-01-31  0:00   ` Nick Roberts
  0 siblings, 0 replies; 14+ messages in thread
From: Nick Roberts @ 1998-01-31  0:00 UTC (permalink / raw)



I would agree with Mats' advice, but, for the record, I think the answer to
your question is more or less as follows.

First, let's assume that there is a function X defined for type Parent in
package Parents as:

   function X (P: Parent) return Result_Type;

and another function X defined for type Child in package Children as:

   function X (C: Child) return Result_Type;

Programmers would then put something like

   with Parents.Children;

in front of their units which were going to use the type Child.  This
'with' clause makes the entities specified by Parents available as well as
those specified by Children.  So the function X which takes Parent as its
parameter would be available as well as the X which takes the type Child as
its parameter (but neither are directly visible, note).

Now, the programmer could either put

   use Parents, Children;

and then declare

   P: Parent;
   C: Child;

and then put

   Y := X(P);
   Z := X(C);

where the two calls to X will be resolved by overloading; or the programmer
could simply declare

   P: Parents.Parent;
   C: Children.Child;

and then put

   Y := Parents.X(P);
   Z := Children.X(C);

where the two calls to X are differentiated explicitly.

Perhaps the point is that the programmer _should_ have to make explicit
reference to the package Parents when using the type Parent, because that's
where it is declared.  If the type Child provides all the same
functionality of Parent (with, perhaps, more added), then the programmer is
using type Child all the time: type Parent remains unused -- it just
provides a 'baseline' from which other types are to be derived. 

-- 

== Nick Roberts ================================================
== Croydon, UK                       ===========================
==                                              ================
== Proprietor, ThoughtWing Software                   ==========
== Independent Software Development Consultant            ======
== Nick.Roberts@dial.pipex.com                              ====
== Voicemail & Fax +44 181-405 1124                          ===
==                                                            ==
==           I live not in myself, but I become               ==
===          Portion of that around me; and to me             ==
====         High mountains are a feeling, but the hum        ==
=======      Of human cities torture.
===========                             -- Byron [Childe Harold]





^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: OOP & Packages in Ada
  1998-01-30  0:00 OOP & Packages in Ada wanker
@ 1998-01-31  0:00 ` Matthew Heaney
  1998-02-01  0:00   ` wanker
  1998-02-04  0:00   ` Don Harrison
  1998-01-31  0:00 ` Mats Weber
  1 sibling, 2 replies; 14+ messages in thread
From: Matthew Heaney @ 1998-01-31  0:00 UTC (permalink / raw)



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

>I've got a question for you.  Assuming we have two packages,
>say Parents and Children, and Children contains a type,
>Child, that is inherited from a type in Parents (Parents.Parent),
>is there a way to easily make all the methods of Parents.Parent
>available to Child, so that just with'ing the Children package will
>make these methods available?  Wrapper functions/procedures
>or renaming might do this, but is there an easier way?

I think you need to rethink the question.

The answer is, no, you cannot make all the "resources" in package Parent
directly visible from package Child.  But are you sure you want to?

Consider an analogy.  Suppose you wrote a technical book, with all kinds of
great infomation.  You use the book for awhile, and later realize there's
more cool stuff you'd like to document.  You'd like to have one book that
has all the old stuff and the new stuff, but it's too late.  Everyone is
already using the original book, and references to information in the book
refer to that book directly.  So what do you do?  You write another book,
and call it Volume II.  For someone to get all the information, instead of
checking out one book, you check out two books.

You must understand the principles of evolution of complex systems.  In
order to reach point B, you have to have traversed throught point A.  Plus,
you can't throw away all the infrastructure already in place when you're in
B, even if you're smarter now and know there's a better way.  What remains
from before is called a "vestigial" characteristic, just as the human
appendix is a "vestigial organ" of what we were before.

The resources exported by a child package are intended to *supplement* the
resources of the parent package, not replace them.  That is why I recommend
you reask the question.  You must consider the packages in their totality,
as a group.

In answer to Mats Weber: No, that the operations were classwide was *not* a
mistake.  It's analogous to a package I know you're intimately familiar
with: package Text_IO, which you discussed in your thesis.  Even if
File_Type (which should have been named Text_File, Brian :-) were tagged,
and you derived from it in a child package, a client of the child still
wouldn't get directly visibility to types Count and Positive_Count - he has
to go to the parent to get them.  Ditto for the exceptions raised by the
primitive operations of File_Type'Class.  So inheritence is not the answer.

It would be really swell if woman could give birth to babies without
appendices.  It would be swell if we could remember more than seven things
at one time (read Miller's famous paper).  It would be just jolly if no one
were near-sighted.  Or could grow limbs back.  But these are features of
the system, and we're stuck with them, like it or not.  In Biomorph Land,
one can only take a small conservative jump, so wherever you are, you are
the product of what you have been (read Dawkins' The Blind Watchmaker, or
D'Arcy Thompson's On Growth and Form, or anything by Stephen Jay Gould). 
Take a different path, and you get a different system.

I'm sorry, I really wish it were some other way.  But it isn't.  That is
the nature of systems.

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




^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: OOP & Packages in Ada
  1998-01-31  0:00 ` Matthew Heaney
@ 1998-02-01  0:00   ` wanker
  1998-02-01  0:00     ` Matthew Heaney
                       ` (4 more replies)
  1998-02-04  0:00   ` Don Harrison
  1 sibling, 5 replies; 14+ messages in thread
From: wanker @ 1998-02-01  0:00 UTC (permalink / raw)



In article <mheaney-ya023680003101981756350001@news.ni.net>,
Matthew Heaney <mheaney@ni.net> wrote:

[Snip -- Question about making methods and other attributes in
 parent packages appear like they are part of child packages]


>The answer is, no, you cannot make all the "resources" in package Parent
>directly visible from package Child.  But are you sure you want to?

Well in this particular case I am.

[Snip -- Good analogy of a multi-volume book]

>You must understand the principles of evolution of complex systems.  In
>order to reach point B, you have to have traversed throught point A.  Plus,
>you can't throw away all the infrastructure already in place when you're in
>B, even if you're smarter now and know there's a better way.  What remains
>from before is called a "vestigial" characteristic, just as the human
>appendix is a "vestigial organ" of what we were before.

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.

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.

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.  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...

Now, if we want to work on a Collie type, and wish to
find out its appearance, reproduction mechanism, locomotion,
fur thickness, bark, and grooming then we'd have to have
a knowledge of a 6 leveled inheritance chain and call
functions with 6 different namespaces qualifiers.


with Objects, Organisms, Animals, Mammals, Dogs, Collies;
for instance:
	Rover : Collies.Collie;


Objects.Appearance (Rover);
Organisms.Reproduction (Rover);
...
Collies.Grooming (Rover);

We can see that this is getting out of hand.  If however the
Collies package managed to make all the methods seem as a part
of it, then one simply does:

with Collies;
Rover : Collies.Collie;

Collies.Collie (Rover);
Collies.Reproduction (Rover);
...
Collies.Grooming (Rover);

Which is a lot simpler, and would be more intuitive -- the user
would not have to know or care if the methods were over-ridden
or not.

I've probably beat the horse to death on this one, but I wanted
to make things clear about how I felt.

Another person suggested with'ing with . to denote children
(I haven't tried that yet), and while this would be better
in that it would not force us to know the dispatching
of the methods, it would still shove the inheritance hierarchy
in our faces.


>
>The resources exported by a child package are intended to *supplement* the
>resources of the parent package, not replace them.  That is why I recommend
>you reask the question.  You must consider the packages in their totality,
>as a group.

Well, maybe I was vague, but when I said "child" I meant a child
as in an inherited class, and not necessarily a child package.  In
this case, the child can replace (customize) the parent's functionality
and supplement it, and in some cases leave it alone.  But this
still leaves the question of the interface open.  What I'm worried
about is the interface to the user.  I don't want the user
to see that Child draws things from Parent.  I want the user
to see Child as a black box and use it, and it would seem that
leaving things as they are, hurts the black box abstraction.


[Snip]

>It would be really swell if woman could give birth to babies without
>appendices.  It would be swell if we could remember more than seven things
>at one time (read Miller's famous paper).  It would be just jolly if no one
>were near-sighted.  Or could grow limbs back.  But these are features of
>the system, and we're stuck with them, like it or not.  In Biomorph Land,
>one can only take a small conservative jump, so wherever you are, you are
>the product of what you have been (read Dawkins' The Blind Watchmaker, or
>D'Arcy Thompson's On Growth and Form, or anything by Stephen Jay Gould). 
>Take a different path, and you get a different system.

Well some of the analogies above aren't really accurate to describe
what I'm thinking of.  I mean giving birth to kids without appendecies
isn't like inheritance, as inheritance ADDs to a system, and
CUSTOMIZes it, but it does not TAKE away.  I mean if the parent
has an appendix as one of its features, then all inherited
types will have appendices too.  


>
>I'm sorry, I really wish it were some other way.  But it isn't.  That is
>the nature of systems.

Thank you for your detailed response.  It certainly provides
quite a bit of food for thought and I hope my response wasn't
overly long-winded.


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






^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: OOP & Packages in Ada
  1998-02-01  0:00   ` wanker
  1998-02-01  0:00     ` Matthew Heaney
@ 1998-02-01  0:00     ` Tom Moran
  1998-02-02  0:00     ` Jon S Anthony
                       ` (2 subsequent siblings)
  4 siblings, 0 replies; 14+ messages in thread
From: Tom Moran @ 1998-02-01  0:00 UTC (permalink / raw)



Is this what you want:
package parent is
  type mammal is tagged null record;
  procedure eat(x : in out mammal);
end parent;

with ada.text_io;
package body parent is
  procedure eat(x : in out mammal) is
  begin ada.text_io.put_line("eat");end eat;
end parent;

with parent;
package child is
  type dog is new parent.mammal with null record;
  procedure bark(x : in out dog);
end child;

with ada.text_io;
package body child is
  procedure bark(x : in out dog) is
  begin ada.text_io.put_line("bark");end bark;
end child;

with child;
procedure user is
  rover : child.dog;
begin
  child.bark(rover);
  child.eat(rover);
end user;
    Note that primitive operations are inherited by child and appear
to user as if child declared them.  This isn't so for other things -
other types, constants, variables, etc.  For instance, if we add
  epitome : mammals;
to the spec of parent, this does not produce a child.epitome (clearly
such a beast would be expected to be different anyway).  If user
wanted to refer to the epitome of mammals, he would "with parent" and
reference parent.epitome.  (Not good naming here, sorry.)  
  The primitive operations supplied by a child may replace or
supplement, or both, those supplied by the parent.




^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: OOP & Packages in Ada
  1998-02-01  0:00   ` wanker
@ 1998-02-01  0:00     ` Matthew Heaney
  1998-02-01  0:00     ` Tom Moran
                       ` (3 subsequent siblings)
  4 siblings, 0 replies; 14+ messages in thread
From: Matthew Heaney @ 1998-02-01  0:00 UTC (permalink / raw)



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




^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: OOP & Packages in Ada
  1998-02-01  0:00   ` wanker
  1998-02-01  0:00     ` Matthew Heaney
  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
  4 siblings, 0 replies; 14+ messages in thread
From: Jon S Anthony @ 1998-02-02  0:00 UTC (permalink / raw)



wanker@exploited.barmy.army writes:

> 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.

Yes, but that is a well known problem with class based OO stuff.


> 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_ part of the dog package.  It's just that they are
_implicitly_ declared.  Of course that implies from a documentation
point of view this doesn't help you much (at all...)


> 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.  Furthermore, the situation gets

Well that's easy enough to fix if you want.  You can make the Dog type
private and then derive if in the private part of the package.  You
then define all the methods you want on Dog in the public part and
indicate they are implemented as the parent Mammal versions in the
private part or the body.  This gives you what you want, but at a cost
of not being able to "conveniently" extend the type later.  Note: all
the polymorphic stuff will still work just fine, you just won't see it
in the clients.


> 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...
> 
> Now, if we want to work on a Collie type, and wish to
> find out its appearance, reproduction mechanism, locomotion,
> fur thickness, bark, and grooming then we'd have to have
> a knowledge of a 6 leveled inheritance chain

Yes, but that's just standard class based OO.


> and call
> functions with 6 different namespaces qualifiers.

But, no, you can simply use the appropriate most specific one you
want.


> with Objects, Organisms, Animals, Mammals, Dogs, Collies;
> for instance:
> 	Rover : Collies.Collie;
> 
> 
> Objects.Appearance (Rover);
> Organisms.Reproduction (Rover);
> ...
> Collies.Grooming (Rover);
> 
> We can see that this is getting out of hand.  If however the
> Collies package managed to make all the methods seem as a part
> of it, then one simply does:

It does.  Read 3.4 carefully.  In particular (17).  For example,

package Animals is

    type Animal is tagged null record;

function Appearance (X : Animal ) return String;

end Animals;


package Animals.Organisms is

    type Organism is new Animal with null record;

function Locomotion (X : Organism) return String;
function Reproduction (X : Organism) return String;

end Animals.Organisms;


package Animals.Organisms.Mammals is

    type Mammal is new Organism with null record;

function Fur_Thickness (X: Mammal) return String;

end Animals.Organisms.Mammals;


package Animals.Organisms.Mammals.Dogs is

    type Dog is new Mammal with null record;

function Bark (X : Dog) return String;

end Animals.Organisms.Mammals.Dogs;


package Animals.Organisms.Mammals.Dogs.Collies is

    type Collie is new Dog with null record;

function Grooming (X: Collie) return String;

end Animals.Organisms.Mammals.Dogs.Collies;


with Animals.Organisms.Mammals.Dogs.Collies;
use Animals.Organisms.Mammals.Dogs.Collies;

with Ada.Text_Io;  use Ada.Text_Io;

procedure Test is

    Rover : Collie;

begin
    Put_Line(
        "Rover : " &
        Appearance(Rover) &
        Reproduction(Rover) &
        Locomotion(Rover) &
        Fur_Thickness(Rover) &
        Bark(Rover) &
        Grooming(Rover));
end Test;

$ gnat test.adb
$ ## no problemo...

> Which is a lot simpler, and would be more intuitive -- the user
> would not have to know or care if the methods were over-ridden
> or not.

Well, then, you should be happy.


/Jon

-- 
Jon Anthony
Synquiry Technologies, Ltd., Belmont, MA 02178, 617.484.3383
"Nightmares - Ha!  The way my life's been going lately,
 Who'd notice?"  -- Londo Mollari




^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: OOP & Packages in Ada
  1998-02-01  0:00   ` wanker
                       ` (2 preceding siblings ...)
  1998-02-02  0:00     ` Jon S Anthony
@ 1998-02-02  0:00     ` Anonymous
  1998-02-03  0:00     ` John English
  4 siblings, 0 replies; 14+ messages in thread
From: Anonymous @ 1998-02-02  0:00 UTC (permalink / raw)



<6asp37$q8b$1@Masala.CC.UH.EDU>
<mheaney-ya023680003101981756350001@news.ni.net>

On 1 Feb 1998 08:14:49 GMT, 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.

Certainly, and that's the problem with derived types in general, and
tagged types specifically. Unless the parent is predefined or declared
in the same declarative region as the child, the result is unreadable.
There is also the problem of coupling; any package that declares a
derived type is highly coupled to the package that declares the parent
type, and as we all know, highly coupled packages are A Bad Thing.

> 
> 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...
> 
> Now, if we want to work on a Collie type, and wish to
> find out its appearance, reproduction mechanism, locomotion,
> fur thickness, bark, and grooming then we'd have to have
> a knowledge of a 6 leveled inheritance chain and call
> functions with 6 different namespaces qualifiers.

Yes, we have to have knowledge of all six packages to use one, but no,
we don't need to use 6 different package names:

> 
> 
> with Objects, Organisms, Animals, Mammals, Dogs, Collies;
> for instance:
> 	Rover : Collies.Collie;
> 
> 
> Objects.Appearance (Rover);
> Organisms.Reproduction (Rover);
> ...
> Collies.Grooming (Rover);

It is the nature of derived types that the operations are defined
implicitly where the type is declared, so one can write

with Collies;
   Rover : Collies.Collie;

   Collies.Appearance (Rover);
   Collies.Reproduction (Rover);

and so on.

However, these operations (Appearance, Reproduction, and so on) do not
appear in the specification of package Collies, which, as you note, is a
nightmare for the user, who has to understand all the packages in the
hierarchy. This is what it means for packages to be highly coupled, and
is why this is A Bad Thing, and To Be Avoided.

>...

Totally An Elephant Aside: As a wanker, are you always pulling your
'ood?

Jeff Carter  PGP:1024/440FBE21
My real e-mail address: ( carter @ innocon . com )
"Hello! Smelly English K...niggets."
Monty Python & the Holy Grail

Posted with Spam Hater - see
http://www.compulink.co.uk/~net-services/spam/













^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: OOP & Packages in Ada
  1998-02-01  0:00   ` wanker
                       ` (3 preceding siblings ...)
  1998-02-02  0:00     ` Anonymous
@ 1998-02-03  0:00     ` John English
  4 siblings, 0 replies; 14+ messages in thread
From: John English @ 1998-02-03  0:00 UTC (permalink / raw)



wanker@exploited.barmy.army wrote:
: Object (Appearance)
:    Organism (Reproduction)
:       Animal (Locomotion)
:          Mammal (Fur_Thickness)
:             Dog (Bark)
:               Collie (Grooming)

: [...lots of big snips...]

: I've probably beat the horse to death on this one, but I wanted
: to make things clear about how I felt.

Hang on. I thought we were talking about Rover the Collie Dog?
Where did the horse come from?  :-)

-----------------------------------------------------------------
 John English              | mailto:je@brighton.ac.uk
 Senior Lecturer           | http://www.it.bton.ac.uk/staff/je
 Dept. of Computing        | ** NON-PROFIT CD FOR CS STUDENTS **
 University of Brighton    |    -- see http://burks.bton.ac.uk
-----------------------------------------------------------------




^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: OOP & Packages in Ada
  1998-01-31  0:00 ` Matthew Heaney
  1998-02-01  0:00   ` wanker
@ 1998-02-04  0:00   ` Don Harrison
  1998-02-04  0:00     ` Matthew Heaney
  1 sibling, 1 reply; 14+ messages in thread
From: Don Harrison @ 1998-02-04  0:00 UTC (permalink / raw)



Matthew Heaney wrote:

: ... (read Dawkins' The Blind Watchmaker, or
:D'Arcy Thompson's On Growth and Form, or anything by Stephen Jay Gould). 

Better still, read Phillip Johnson's "Darwin on Trial" which refutes both. :)

Q: What's the definition of a "vestigal" organ?
A: One whose purpose isn't understood.


Don.
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
Don Harrison        doELIDEnh@syd.csa.com.au






^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: OOP & Packages in Ada
  1998-02-04  0:00   ` Don Harrison
@ 1998-02-04  0:00     ` Matthew Heaney
  1998-02-05  0:00       ` Don Harrison
  0 siblings, 1 reply; 14+ messages in thread
From: Matthew Heaney @ 1998-02-04  0:00 UTC (permalink / raw)



In article <EnuAD7.217@syd.csa.com.au>, nospam@thanks.com.au wrote:

>: ... (read Dawkins' The Blind Watchmaker, or
>:D'Arcy Thompson's On Growth and Form, or anything by Stephen Jay Gould). 
>
>Better still, read Phillip Johnson's "Darwin on Trial" which refutes both. :)

My point is that systems of any kind evolve, including large software
systems.  The object paradigm facilitates evolution of software systems via
polymorphism: changes don't break existing code.  Let us be reminded of
what John Gall said in Systemantics:

"A complex system that works is invariabley found to have evolved from a
simple system that worked."

and conversely

"A complex system designed from scratch never works and cannot be made to work."

The latter quote aptly describes many software projects.

Yes, there is some religious dogma that repudiates evolution of living
systems, but I think we can all agree that at a minimum large software
systems evolve, and that you better plan for this evolution to happen.

>Q: What's the definition of a "vestigal" organ?
>A: One whose purpose isn't understood.

How many times have you looked at old code that you know you could do
better now, but don't bother changing it because it's "good enough"? 
That's a vestigal organ, and there's nothing to that isn't "understood"
about its behavior at all.

When you're done with Johnson book (I haven't read it yet), then sit down
and read Evolution and the Myth of Creationism, by Tim M. Berra, and The
Panda's Thumb, by Stephen Jay Gould.

Actually, just last night I picked up Dawkin's first book, The Selfish
Gene.  It's on deck right behind the book I'm reading now, Daniel Dennet's
Consciousness Explained.

No entelechy for me thank you very much, I got systems to build.




^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: OOP & Packages in Ada
  1998-02-04  0:00     ` Matthew Heaney
@ 1998-02-05  0:00       ` Don Harrison
  1998-02-06  0:00         ` Bob Collins
  0 siblings, 1 reply; 14+ messages in thread
From: Don Harrison @ 1998-02-05  0:00 UTC (permalink / raw)



Matthew Heaney wrote:

:In article <EnuAD7.217@syd.csa.com.au>, nospam@thanks.com.au wrote:
:
:>: ... (read Dawkins' The Blind Watchmaker, or
:>:D'Arcy Thompson's On Growth and Form, or anything by Stephen Jay Gould). 
:>
:>Better still, read Phillip Johnson's "Darwin on Trial" which refutes both. :)

BTW, "both" refers to Dawkins and Gould. I'm not familiar with Thompson's work.

:My point is that systems of any kind evolve, including large software
:systems...  

Yes, that's true of software systems. However, I'm referring to biological 
systems. It's an established fact that organisms can micromutate to accomodate 
changes in their environment. However, it's quite another thing to claim that 
changes in *species* can occur through:

  a) Accumulated micromutations (traditional Darwinism as espoused by Dawkins,
     for example), or
  b) Macromutations (Gould's theory of Punctuated Equilibrium)

through a process called "natural" selection.

Contrary to what many would like to think, neither of these theories have 
been proven.


:Yes, there is some religious dogma that repudiates evolution of living
:systems, ...

My reference is to Gould's book. If you read it, you'll discover that it isn't 
based on "religious dogma". Rather, in assessing the claims of Darwinism,
Johnson has stuck to factual evidence and avoided prior assumptions, including 
those based on religious belief. This is in stark contrast to Dawkins' and 
Gould's writings which reflect numerous unstated assumptions derived from the 
Darwinist belief system. 


:>Q: What's the definition of a "vestigal" organ?
:>A: One whose purpose isn't understood.

My point here is to take issue with your assumption of evolution of biological 
organs as implied by the word "vestigal".

:When you're done with Johnson book (I haven't read it yet), then sit down
:and read Evolution and the Myth of Creationism, by Tim M. Berra, and The
:Panda's Thumb, by Stephen Jay Gould.

I have finished "Darwin on Trial" and intend reading "Evolution: A Theory in
Crisis" by Michael Denton next. I've read parts of Dawkins' "Climbing Mount
Improbable" and Gould's "Ever Since Darwin". If I find the time, I'll take a 
look at Berra. 


Don.
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
Don Harrison        doELIDEnh@syd.csa.com.au






^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: OOP & Packages in Ada
  1998-02-05  0:00       ` Don Harrison
@ 1998-02-06  0:00         ` Bob Collins
  0 siblings, 0 replies; 14+ messages in thread
From: Bob Collins @ 1998-02-06  0:00 UTC (permalink / raw)



In article <Envu3G.LnD@syd.csa.com.au>, nospam@thanks.com.au wrote:

> I have finished "Darwin on Trial" and intend reading "Evolution: A Theory in
> Crisis" by Michael Denton next. I've read parts of Dawkins' "Climbing Mount
> Improbable" and Gould's "Ever Since Darwin". If I find the time, I'll take a 
> look at Berra. 

If you want as clear as explanation as there is as to why
"the impossibility of macroevolution" is an intellectual
crock, try Daniel Dennett's _Darwin's Dangerous Idea_.

-- 
Bob Collins  <mailto:collins@cs.wm.edu>  <http://ratbert.cs.wm.edu>




^ permalink raw reply	[flat|nested] 14+ messages in thread

end of thread, other threads:[~1998-02-06  0:00 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
1998-01-30  0:00 OOP & Packages in Ada wanker
1998-01-31  0:00 ` Matthew Heaney
1998-02-01  0:00   ` wanker
1998-02-01  0:00     ` Matthew Heaney
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
1998-01-31  0:00 ` Mats Weber
1998-01-31  0:00   ` Nick Roberts

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