From: eachus@Dr_No.mitre.org (Robert I. Eachus)
Newsgroups: comp.lang.ada
Subject: Re: MI - clutching at straws
Date: 23 Aug 92 22:30:50 GMT
Organization: The Mitre Corp., Bedford, MA.

In article <1992Aug23.171350.27117@Urmel.Informatik.RWTH-Aachen.DE> pk@rwthi3.informatik.rwth-aachen.de (Peter Klein) writes:

   Consider the following example: I start with an abstract data type
   for a graph.  Now I augment the basic type in several independant
   ways, let's say to make attributed, node- and edge-labeled graphs.
   Finally, I would like to have some special graphs, e.g. abstract
   syntax graphs or binary trees, which combine one or more of the
   above extensions. How can I express this without violating the
   abstractness of the involved data types? Maybe somebody's got some
   clever answer. Otherwise, I will keep thinking that MI is sometimes
   appropriate.

   Okay, challenge accepted...

   First, let's create the basic graph package.  The "normal" way to
do this in Ada is to use a model where different graphs are different
instances of a generic package, but other models are possible.  So
lets use a generic which exports an abstract type...

   generic
     type Node_Data is private;
     type Edge_Data is private;
   package Graphs is

     type Node is private;
     type Edge is private;
     type Graph is private;

     function Data (N: in Node) return Node_Data;
     function Data (E: in Edge) return Edge_Data;
     procedure Set_Data(N: in out Node; ND: in Node_Data);
     procedure Set_Data(E: in out Edge; ED: in Edge_Data);
     -- No graph parameter needed implicit in the node or edge.

     function Create return Graph;

     function Create(ND: in Node_Data G: in Graph) return Node;
     -- Need to specify the graph.

     function Create(From, To: Node; ED: in Edge_Data) return Edge;
     -- Graph come from the nodes which must belong to the same graph.

     --- etc,.
  end Graph;

    In Ada 9X, I can play several games with this, such as making the
graph type a tagged type. (And playing games in the body to make
derivation work.)  But to do the type of thing you want to do, using a
tagged types for the Edge_Data and Node_Data types may suffice.  I
could also provide separate directed and undirected edge types, but it
is probably better to leave the end of the edge distinguished at this
level, and conceal this fact if necessary.

    In any case now most of the augmentations are natural and done by
different instantiations.  The special graphs, such as binary trees,
would be done by instantiating the GRAPHS package then adding
additional operations at a higher level.  In Ada 9X this can be done
by writing a binary tree generic which takes an instantiation of
GRAPHS as a parameter.  In Ada 83, you can do the same sort of thing,
but the declaration gets much messier.  (All of the visible types and
operations of the GRAPHS package must be passed as individual generic
parameters.)

    Now it is possible to decorate a single GRAPHS instance with all
of the various special graph add ons.  In general, many of the
combinations wouldn't make sense, but that is an issue (in Ada) for
the programmer not the compiler.

    I could ring a lot of changes on the theme, but in general, the
lesson is that, IN ADA, anything that might possibly be done with
multiple inheritance is probably better done with generics.  Notice
that in this example, I went out of my way to make single inheritance
possible.  A pure generic solution seems much more appropriate.  This
says nothing about whether or not MI is useful in other languages,
just that there is no reason to add it to Ada.
--

					Robert I. Eachus

with STANDARD_DISCLAIMER;
use  STANDARD_DISCLAIMER;
function MESSAGE (TEXT: in CLEVER_IDEAS) return BETTER_IDEAS is...
Newsgroups: comp.lang.ada