comp.lang.ada
 help / color / mirror / Atom feed
From: jgv@swl.msd.ray.com (John Volan)
Subject: Re: Decoupled Mutual Recursion Challenger
Date: Wed, 12 Oct 1994 13:17:10 GMT
Date: 1994-10-12T13:17:10+00:00	[thread overview]
Message-ID: <1994Oct12.131710.12631@swlvx2.msd.ray.com> (raw)
In-Reply-To: 37e5m6$oh0@watnews1.watson.ibm.com

ncohen@watson.ibm.com (Norman H. Cohen) writes:

>In article <1994Oct7.130100.26953@swlvx2.msd.ray.com>, jgv@swl.msd.ray.com
>(John Volan) writes: 

>|> The trouble with solutions that exploit inheritance is that they use
>|> it solely as a mechanism for decoupling, without (as Adam Beneschan
>|> pointed out) correlating it to any true generalization/specialization
>|> relationship present within the problem domain.  It can be argued that
>|> this is an abuse of the inheritance mechanism, an example of the
>|> reason why inheritance has been branded by some as the "GOTO of the
>|> Nineties".  In fact, such inheritance schemes can even *get in the
>|> way* of more "legitimate" uses of inheritance that do implement
>|> generalization/specialization relationships.

>I think this is a natural and appropriate use of inheritance.  To review,
>the scheme in question is: 

[snip outline of scheme -- but excerpted again below]

>The type Type_1_Parent models some real-world entity, perhaps an office
>or an employee.  When a type models a real-world entity, it does not
>model every property of that entity, only those that are relevant to the
>intended use of the type.  For example, a type modeling an employee might
>not include a Favorite_Scotch component if that information is not
>relevant to the application.  The only feature of Type_1_Parent is its
>ability to be pointed to by a Type_1_Pointer value.

>The type Type_1 is a specialization of Type_1_Parent.  The real-world
>entity it models happens to be the same as that modeled by Type_1_Parent,
>but it provides a more specialized VIEW of that entity, one that offers
>not only the ability to be pointed to by a Type_1_Pointer value, but a
>number of primitive subprograms as well.  An instance of Type_1 "is an"
>instance of Type_1_Parent, because it can be used in the same way as any
>other instance of Type_1 (and in additional ways as well).

>There is nothing wrong with a class and a subclass modeling the same
>real-world entity, but with the subclass providing a more specialized
>view of that entity, with a more complete programming interface.

Everything you say is reasonable from a certain perspective, and I
have no doubt that this scheme can be useful in some applications, as
long as the designers share the same perspective.  But you still have
not addressed the challenge: Show that this use of inheritance
(providing two views of the same class of real-world entities) does
not interfere with the more "customary" use of inheritance (support
for the relationship of generalization/specialization between two
different classes of real-world entities).

To review the challenge:


>    package Type_1_Parent_Package is

     -- e.g. Employee

>       type Type_1_Parent is tagged null record;
>       type Type_1_Pointer is access all Type_1_Parent'Class;
>    end Type_1_Parent_Package;
>
>    package Type_2_Parent_Package is

     -- e.g. Office

>       type Type_2_Parent is tagged null record;
>       type Type_2_Pointer is access all Type_2_Parent'Class;
>    end Type_2_Parent_Package;

     package Type_3_Parent_Package is
     -- e.g. Project
        type Type_3_Parent is tagged null record;
        type Type_3_Pointer is access all Type_3_Parent'Class;
     end Type_3_Parent_Package;

     package Specialization_Of_1_Parent_Package is
     -- e.g. Manager
        type Specialization_Of_1_Parent is tagged null record;
        type Specialization_Of_1_Pointer is 
          access all Specialization_Of_1_Parent'Class;
     end Specialization_Of_1_Parent_Package;

>    with Type_2_Parent_Package;

     -- add this:
     with Specialization_Of_1_Parent_Package;

>    package Type_1_Parent_Package.Refinement is
>       type Type_1 is new Type_1_Parent with private;
>       -- declaration of various primitive Type_1 subprograms, including
>       --   some involving Type_2_Pointer

        --   as well as some involving Specialization_Of_1_Pointer

>    private
>       type Type_1 is new Type_1_Parent with
>          record
>             Associated_Type_2_Value: Type_2_Pointer;

              Associated_Specialization_Of_1 : Specialization_Of_1_Pointer;

>             -- other components
>          end record;
>    end Type_1_Parent_Package.Refinement;
>
>    with Type_1_Parent_Package;
>    package Type_2_Parent_Package.Refinement is
>       type Type_2 is new Type_2_Parent with private;
>       -- declaration of various primitive Type_2 subprograms, including
>       --   some involving Type_1_Pointer
>    private
>       type Type_2 is new Type_2_Parent with
>          record
>             Associated_Type_1_Value: Type_1_Pointer;
>             -- other components
>          end record;
>    end Type_2_Parent_Package.Refinement;

     with Type_1_Parent_Package.Refinement;
     with Type_3_Parent_Package; -- If this "with" were not already here, then
                                 -- adding it should not affect Type_2.
     package Specialization_Of_1_Parent_Package.Refinement is

       -- DILEMMA: Should we say:

       type Specialization_Of_1 is new Specialization_Of_1_Parent with private;
       -- using inheritance to provide a more complete view

       -- or should we say:

       type Specialization_Of_1 is new Type_1 with private;
       -- using inheritance for a real-world generalization/specialization

        -- declaration of various primitive Specialization_Of_1 subprograms, 
        --   including some involving Type_1_Pointer
        --   and some involving Type_3_Pointer
     private
       type Specialization_Of_1 is new ???? with
         record
           Associated_Type_1_Value : Type_1_Pointer; -- assuming cardinality=1
           Associated_Type_3_Value : Type_3_Pointer; -- assuming cardinality=1
           -- other components
         end record;
     end Specialization_Of_1_Parent_Package.Refinement;

     -- (Of course, in all of the above, assume that there is a liberal
     -- sprinkling of "use" clauses :-)

>--
>Norman H. Cohen    ncohen@watson.ibm.com

Let me state it categorically: I think that using the mechanism of
inheritance to solve the problem of decoupled mutual recursion is
misguided.  Luckily, I think there is a better solution, but it
involves another feature of Ada entirely ...

-- John Volan

--------------------------------------------------------------------------------
--  Me : Person := (Name                => "John Volan",
--                  Company             => "Raytheon Missile Systems Division",
--                  E_Mail_Address      => "jgv@swl.msd.ray.com",
--                  Affiliation         => "Enthusiastic member of Team Ada!",
--                  Humorous_Disclaimer => "These opinions are undefined " &
--                                         "by my employer and therefore " &
--                                         "any use of them would be "     &
--                                         "totally erroneous.");
--------------------------------------------------------------------------------



  reply	other threads:[~1994-10-12 13:17 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <1994Oct7.130100.26953@swlvx2.msd.ray.com>
1994-10-11 13:58 ` Decoupled Mutual Recursion Challenger [Was: Mut. Recurs. in Ada9X w/o Breaking Encaps.? (LONG)] Norman H. Cohen
1994-10-12 13:17   ` John Volan [this message]
     [not found] ` <1994Oct7.165517@di.epfl.ch>
     [not found]   ` <1994Oct7.222716.8690@swlvx2.msd.ray.com>
     [not found]     ` <1994Oct11.122356@di.epfl.ch>
1994-10-11 23:34       ` Decoupled Mutual Recursion Challenger John Volan
replies disabled

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