comp.lang.ada
 help / color / mirror / Atom feed
From: Matthew Heaney <matthew_heaney@acm.org>
Subject: Re: Can't export object of private type
Date: 1999/03/09
Date: 1999-03-09T00:00:00+00:00	[thread overview]
Message-ID: <m3hfrux6dn.fsf@mheaney.ni.net> (raw)
In-Reply-To: F8BFH1.6FF@syd.csa.com.au

nospam@thanks.com.au (Don Harrison) writes:

> Nick Roberts wrote:
> 
> :|:Also, you need to remove the function Solo_T from package T (it does
> :nothing
>
> Yes, you're right. As the code stands, it isn't necessary. What I
> really want is an abstract primitive operation, not so much for
> polymorphism, but so that derivations are forced to supply an access
> function to their (private) variable "Self". This is a form of
> contract which derivations must meet.

You can't enforce this using the type system.

This is like declaring a type, and then trying to have an operation that
forces clients to declare instances of the type.  Huh???

There is a very practical reason why you'll need an accessor function:
no one will be able to use your singleton if you don't provide one!


> :|:and move the declaration of Self from the private part
> :|:of package T.Child (where it doesn't need to be, and will cause an
> :|:unnecessary dependency) to the package's body.
>
> Got you. There are two opposing needs here:
> 
>   a) On the other, it's convenient for all private declarations 
>      to be in the one place (rather than being split between private 
>      part of spec and body)....

I would declare the instance in the body.  The reason is that there
might be other abstractions that are needed by the instance.  

If you declare the instance in the spec, then you'll have to move those
with's into the spec too, which can cause unnecessary recompilations.

> Just wondering.. Would private child packages have been a better 
> alternative to nested packages? [I have a pathological aversion to nested 
> packages.]

If you have a choice between a child and a nested package, then use a
child.  The reason, of course, is to push module dependencies into the
child.  By moving the dependency to a child, you only have to recompile
the subtree, if that module changes.

This motivated by package design in my "Abstract Factory Revisited"
article in the ACM patterns archive.  

<http://www.acm.org/archives/patterns.html>

Maze_Type has a dependency on Maze_Room, because one of its operations
takes a room as a return value:


  type Maze_Type (<>) is limited private;

  function Get_Room 
    (Number  : in     Positive;
     Of_Maze : access Maze_Type) return Room_Handle;

In the original version, I had this:

package Mazes is

  type Maze_Type (<>) is limited private;

...
  type Maze_Room is new Maze_Item with private;

  <room ops>

  function Get_Room (Number : ...


With this organization of types, then the entire subsystem (rooted at
Mazes) has a dependency on Maze_Type, Maze_Item, and Maze_Room.  If any
of those types changes (say, because you need to add an operation), then
every package in the subsystem must get recompiled.

I reasoned that the only type that really needs to go in the root spec
is Maze_Item, because that's the root type for all the things you put in
a maze game (walls, doors, and rooms all derive from that type).

But no one depends Maze_Type except the client.  So I moved that type
into a child package, which allowed me to move the declaration of the
room type into a child package.  Like this:

package Mazes.Rooms is

  type Maze_Room is new Maze_Item with private;

...
end Mazes.Rooms;


with Mazes.Rooms;
package Mazes.Games is

  type Maze_Type (<>) is limited private;

  function Get_Room 
    (Number  : in     Positive;
     Of_Maze : access Maze_Type) return Rooms.Room_Handle;

...
end Mazes.Games;


Now, with this improved organization, if Maze_Room type changes, then
only clients of that one package (like Mazes.Games) need to be
recompiled.

If Maze_Type changes, then only clients of that package need to be
recompiled.

The rest of the children of package Mazes are oblivious to changes in
Maze_Room or Maze_Type, because they no longer depend on those types.

In Ada especially, you always have to be thinking about how to remove
module dependencies.  Indeed, the child package facility was created
_expressly_ to allow you to remove dependencies, by moving the
dependency to a subtree.  

There is an analogy to deep type hierarchies.  The higher in the
hierarchy you make a change, the more clients have to get recompiled.
This problem is so pernicious and so common it has a name: the "fragile
base class" problem.

In Ada, you have a similar problem for modules.  Change the root module
in a subsystem, and _every_ module in the subsystem has to get
recompiled.

You cannot just be thinking of programming in the abstract.  You must
also be thinking about the actual construction of systems.  Frequent
recompilations will do you in, and you must take active steps to avoid
it.  

That means careful module design is required.  Move module dependencies
to a body whenever possible, and push spec dependencies downward in the
package hierarchy.

In my example above, two types were moved moved from a parent package to
two children.  This protects other children in that hierarchy from
changes in those types.

This is one of the reasons I prefer to declare singleton abstractions as
state machine packages whenever possible, because the "representation"
of that "object" can stay in the body.  

To use a type means you have to implement the type in the private region
of the spec, which means the entities you need to implement that type
have to get with'd by the spec.  

Change one of those other packages, and every package that with's yours
will have to be recompiled.  This would not be true if those
dependencies were moved into the body.

This is basically why always say, Don't implement a singleton as a type,
unless you have a compelling need to.  It just creates module
dependencies that wouldn't be there otherwise.

'nuff said,
Matt





























  reply	other threads:[~1999-03-09  0:00 UTC|newest]

Thread overview: 128+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <F7JoCB.JxB@syd.csa.com.au>
1999-02-24  0:00 ` Can't export object of private type Don Harrison
1999-02-24  0:00   ` Tom Moran
1999-02-24  0:00   ` Samuel Mize
1999-02-24  0:00     ` Tucker Taft
1999-02-25  0:00     ` Don Harrison
1999-02-25  0:00       ` Samuel Mize
1999-02-26  0:00         ` Don Harrison
1999-02-27  0:00           ` Nick Roberts
1999-03-01  0:00             ` Don Harrison
1999-03-01  0:00               ` Matthew Heaney
1999-03-01  0:00                 ` Nick Roberts
1999-03-01  0:00               ` Nick Roberts
1999-03-01  0:00                 ` Don Harrison
1999-03-02  0:00                   ` Matthew Heaney
1999-03-03  0:00                     ` Don Harrison
1999-03-03  0:00                       ` Samuel Mize
1999-03-04  0:00                         ` Don Harrison
1999-03-07  0:00                     ` Ehud Lamm
1999-03-03  0:00               ` Robert A Duff
1999-03-04  0:00                 ` Don Harrison
1999-03-04  0:00                   ` Robert A Duff
1999-03-01  0:00             ` Don Harrison
1999-03-02  0:00               ` Matthew Heaney
1999-02-28  0:00         ` Matthew Heaney
1999-03-01  0:00           ` Nick Roberts
1999-03-01  0:00             ` Matthew Heaney
1999-03-02  0:00               ` Nick Roberts
1999-03-01  0:00             ` Matthew Heaney
1999-03-01  0:00           ` Samuel Mize
1999-02-25  0:00       ` fraser
1999-02-26  0:00         ` Don Harrison
1999-02-26  0:00           ` Samuel Mize
1999-03-01  0:00             ` Don Harrison
1999-03-01  0:00               ` Matthew Heaney
1999-03-02  0:00               ` fraser
1999-03-03  0:00                 ` Don Harrison
     [not found]           ` <7b6nqe$75m$1@remarq.com>
1999-02-26  0:00             ` fraser
1999-02-27  0:00               ` Nick Roberts
1999-02-26  0:00           ` fraser
1999-03-01  0:00             ` Don Harrison
1999-03-01  0:00               ` Matthew Heaney
1999-02-28  0:00           ` Matthew Heaney
1999-02-28  0:00         ` Matthew Heaney
1999-02-25  0:00       ` robert_dewar
1999-02-26  0:00         ` Don Harrison
1999-02-26  0:00           ` robert_dewar
1999-02-26  0:00             ` bourguet
1999-02-26  0:00               ` Samuel T. Harris
1999-02-27  0:00                 ` Simon Wright
1999-02-27  0:00                 ` Jean-Pierre Rosen
1999-02-28  0:00               ` dewar
1999-03-01  0:00                 ` bourguet
1999-02-26  0:00             ` dennison
1999-03-01  0:00             ` Stephen Leake
1999-03-01  0:00             ` Don Harrison
1999-03-01  0:00               ` robert_dewar
1999-03-03  0:00                 ` Don Harrison
1999-03-03  0:00                   ` robert_dewar
1999-02-27  0:00         ` Brian Rogoff
1999-03-01  0:00           ` robert_dewar
1999-02-28  0:00       ` Matthew Heaney
1999-03-01  0:00       ` Tom Moran
1999-03-02  0:00         ` Matthew Heaney
1999-03-02  0:00           ` Tom Moran
1999-03-02  0:00             ` Matthew Heaney
1999-03-02  0:00               ` Tom Moran
1999-03-02  0:00                 ` Matthew Heaney
1999-03-02  0:00                   ` nabbasi
1999-03-02  0:00                     ` Matthew Heaney
1999-03-03  0:00                   ` Don Harrison
1999-03-03  0:00                     ` Single Extension; Polymorphic Arrays Nick Roberts
1999-03-03  0:00                       ` Nick Roberts
1999-03-08  0:00                         ` Matthew Heaney
1999-03-08  0:00                           ` Nick Roberts
1999-03-08  0:00                           ` Tucker Taft
     [not found]                             ` <m3ogm40wav.fsf@mheaney.ni.net>
1999-03-08  0:00                               ` Nick Roberts
1999-03-08  0:00                               ` Tucker Taft
1999-03-08  0:00                                 ` dennison
1999-03-09  0:00                                 ` Nick Roberts
1999-03-03  0:00               ` Can't export object of private type Don Harrison
1999-03-03  0:00                 ` Don Harrison
1999-03-03  0:00                   ` Nick Roberts
1999-03-04  0:00                     ` Don Harrison
1999-03-04  0:00                       ` fraser
1999-03-09  0:00                         ` Don Harrison
1999-03-04  0:00                       ` Nick Roberts
1999-03-08  0:00                         ` Matthew Heaney
1999-03-09  0:00                         ` Don Harrison
1999-03-09  0:00                           ` Matthew Heaney [this message]
1999-03-09  0:00                             ` Nick Roberts
1999-03-10  0:00                             ` Don Harrison
1999-03-10  0:00                               ` Matthew Heaney
1999-03-04  0:00                       ` Nick Roberts
1999-03-04  0:00                         ` robert_dewar
1999-03-05  0:00                           ` Nick Roberts
1999-03-05  0:00                         ` Robert A Duff
1999-03-05  0:00                           ` Abstract Subprograms of Untagged Types Nick Roberts
1999-03-05  0:00                             ` Tucker Taft
1999-03-05  0:00                               ` Nick Roberts
1999-03-06  0:00                               ` robert_dewar
1999-03-05  0:00                             ` robert_dewar
1999-03-08  0:00                     ` Can't export object of private type Matthew Heaney
1999-03-08  0:00                       ` Nick Roberts
1999-03-08  0:00                 ` Matthew Heaney
1999-03-10  0:00                   ` Don Harrison
1999-03-10  0:00                     ` Matthew Heaney
1999-03-10  0:00                       ` dennison
1999-03-10  0:00                         ` robert_dewar
1999-03-10  0:00                           ` dennison
1999-03-10  0:00                             ` robert_dewar
1999-03-10  0:00                               ` dennison
1999-03-11  0:00                                 ` bill
1999-03-11  0:00                                   ` Scott Ingram
1999-03-11  0:00                                     ` Larry Kilgallen
1999-03-11  0:00                                   ` dennison
1999-03-12  0:00                                   ` dewar
1999-03-11  0:00                                 ` dennison
1999-03-11  0:00                                 ` robert_dewar
1999-03-11  0:00                                   ` Don Harrison
1999-03-12  0:00                                     ` robert_dewar
1999-03-11  0:00                           ` Don Harrison
1999-03-10  0:00                         ` Robert A Duff
1999-03-10  0:00                           ` robert_dewar
1999-03-10  0:00                           ` dennison
1999-03-11  0:00                             ` dennison
1999-03-03  0:00           ` Don Harrison
1999-02-28  0:00     ` Matthew Heaney
1999-02-28  0:00   ` Matthew Heaney
replies disabled

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