comp.lang.ada
 help / color / mirror / Atom feed
From: jgv@swl.msd.ray.com (John Volan)
Subject: Re: Mut. Recurs. in Ada9X w/o Breaking Encaps.? (LONG)
Date: Sun, 2 Oct 1994 16:41:05 GMT
Date: 1994-10-02T16:41:05+00:00	[thread overview]
Message-ID: <1994Oct2.164105.13127@swlvx2.msd.ray.com> (raw)
In-Reply-To: Cwyzx4.H3K@irvine.com


adam@irvine.com (Adam Beneschan) writes:

>I'd like to chime in and say I'm not satisfied either.... 

I fear there may be many of us out there.

[snip]

>And based on my experience writing large Ada 83 programs, my gut
>instinct is that this is the sort of flaw that will be cursed by many
>9X users down the line...

That's my fear as well.  That's why I've been trying very hard to find
an Ada9X solution.  Eiffel can do decoupled mutual recursion standing on its
head.  Smalltalk virtually swims in a sea of decoupled mutual recursion 
(trivial in a typeless language).  I suspect C++ can actually manage it as well.
(Can any C++ folks confirm this?  Realize what I mean: Can you forward-declare 
a class and then *not* complete its declaration in the same header file, and 
yet complete the declaration of a client class?  Or do you *have* to declare 
both classes in the same header file?)

We want Ada9X to be successful.  We want Ada9X to attract programmers who
might not have considered using Ada before.  If something is trivial in other
languages, it is not necessary that it be *trivial* in Ada9X.  But it must
at least be *feasible*.

[snip]

>What I think John wants (and I concur) is some way for package
>specifications to use accesses to types in other packages that haven't
>been compiled yet--sort of like a forward declaration that crosses
>package boundaries.  Perhaps something like this could be added to 
>Ada 0X or whatever the next revision of the language would be.

I agree wholeheartedly with the *goal*, but not with the *means* you suggest.

Goal: Some kind of "forward declaration" that crosses package boundaries.
(Good and worthy goal.)

Means: Some way for package specifications to use access types in other
packages that *haven't been compiled yet*.  (Horrible means, terrible 
implications, shudder, shudder :-)

Actually, I have a better idea.  Let's take a bit of inspiration from a
notion that is already intrinsic to the design of Ada:  Although a package is
considered to be a single, self-contained, organic entity -- a *unit* of program
modularity -- nevertheless it is syntactically broken up into two *parts* that
present complementary *views* of that single unit -- two views which can be
*separately compiled*. They are: (1) the package specification, which presents
the *interface* view of the package, and (2) the package body, which presents
the *implementation* view of the package.

All that is really needed is to a break off a third syntactic part that can
offer a view of the package where we can make "forward declarations"  -- or
rather, where "incomplete" declarations could be tolerated, because they
will eventually be completed in the package specification.  We could offer up
this new part as a separately-compilable piece of code.  In keeping with the
long-standing Ada practice of *recycling* reserved words for new uses rather 
than creating new ones (bet you didn't know that Ada language designers were 
environmentalists! :-), let's call this new package part a "package abstract"
(where "abstract" is a noun rather than an adjective, like the "abstract"
of an article).  

Rules:

(1) A package abstract would be considered a declarative region contiguous with
    the public part of the corresponding package specification.  The spec
    would implicitly have visibility to any declaration that appeared in its
    corresponding package abstract.

(2) To avoid a situation analogous to the problem of "optional" package bodies
    in Ada 83, we would need to syntactically distinguish ordinary package 
    specs from those that have an abstract. The following would be illegal:

    (a) Compiling an ordinary spec when a package abstract with the same name
        is already in the library.

    (b) Compiling a package abstract when an ordinary package spec with the same
        name is already in the library.

    (c) Compiling a package-spec-with-abstract before its corresponding 
        package abstract.  (Analogous to compiling a package body before
        the corresponding package spec.)

    (Of course, for the GNAT compiler, you'd have to translate these into 
    source-file dependency rules rather than order-of-compilation rules.)

(3) We would also need an alternate syntax for the "with" clause, to allow a
    client to import only the abstract of a package. Such a client would only 
    be able to make use of those declarations from the package abstract that
    were actually "complete".  Later (in its body, say) a client could import
    the full spec via a normal "with" clause, and this would give it access
    to the complete view of all the public features of the package.

Example:

	----------------------------------------------------------------------

	abstract of package Employee is -- note additional syntax

	  type Object is tagged limited private;
	    -- This is an example of an incomplete declaration that 
            -- can be "tolerated" in a package abstract

          type Pointer is access all Object'Class;
	  None : constant Pointer := null;
            -- These are examples of complete declarations (or are they?)

	end Employee;

	----------------------------------------------------------------------

	with abstract of Office; -- examples of import of package abstracts
	with abstract of Memo;
	with abstract of Meeting;
	with abstract of Job_Description;
	...

	package with abstract Employee is -- note additional syntax

	  ...

	  function Office_Occupied_By (The_Employee : in Employee.Object'Class)
	    return Office.Pointer;

	  procedure Occupy_Office (The_Employee : in out Employee.Object'Class;
	                           New_Office   : in     Office.Pointer);
	  -- mutually recursive with Office.Accomodate_Employee

	  ...

	private
	  type Object is tagged limited
	    record
	      ... 
	      Its_Occupied_Office : Office.Pointer;
	      Its_Job_Description : Job_Description.Pointer;
	      ...
	      ... 
	    end record;
	end Employee;

	----------------------------------------------------------------------

	with Office; -- normal import of full package specifications
	with Memo;
	with Meeting;
	with Job_Description;
	...

	package body Employee is

	  ...

	  function Office_Occupied_By (The_Employee : in Employee.Object'Class)
	    return Office.Pointer is
	  begin
	    return The_Empoyee.Its_Occupied_Office;
	  end Office_Occupied_By;

	  procedure Occupy_Office (The_Employee : in out Employee.Object'Class;
				   New_Office   : in     Office.Pointer) is
	    use type Office.Pointer;
	  begin
	    if New_Office /= Office.None and then
	       New_Office /= The_Employee.Its_Occupied_Office then
	    begin
	      Employee.Vacate_Office (The_Employee);
	      The_Employee.Its_Occupied_Office := New_Office;
	      Office.Accomodate_Employee (The_Office.all, The_Employee'Access);
	    end if;
	  end Occupy_Office;
	
	  ...

	end Employee;

	----------------------------------------------------------------------

Obvious Problems:

(1) It's certainly pretty late in the game to consider this kind of thing
    for Ada9X.  Maybe Ada0X could do something with it.  Also, I haven't
    studied the whole MRT history, so I don't know if someone has already
    thought of something like this.  I don't want to take credit (or blame :-)
    for someone else's idea.

(2) In making this suggestion, I am engaging in the execrable practice of
    "YALFing" (where YALF = "Yet Another Language Feature" :-).  This extra 
    feature might make it trivial to write code in this particular style, 
    but is it worth the added complexity to the language?  (I'm still holding 
    out hope that there is some elegant way of combining the *existing* features
    of Ada 9X to support this coding style.)

(3) Is a pointer type really "complete" by the end of a package abstract?
    What if, instead of a private type, the Object type in the package abstract
    were an incomplete type declaration that got completed in the *public*
    part of the package spec?  What if that complete type were a record type
    or an array type?  Would a client-of-spec be able to use record-component
    or array-indexing syntax with the pointer type, whereas a client-of-abstract
    would not?  

(4) Could a package-with-abstract be generic?  Where would the generic clause
    go?  On the abstract?  On the spec?  On both?  If both, would they have to
    be identical, or could the abstract introduce some generic formal parameters
    and the spec introduce more?  How would instantiation work?  Would you need
    an alternate syntax for instantiation-of-abstract vs. instantiation-of-spec?
    What if a client instantiated the abstract and then later instantiated the
    spec with the same name and actual parameters?  Would they be two views of 
    the same instantiated package, or two different instantiated packages?  
    What if you tried this at the library level?  What implications does all 
    of this have for the generic contract model?

Not being a language lawyer, I'm sure there must be other conceptual
difficulties and complexities.  I can't begin to assess what it would cost
you compiler-writers out there to try to implement this feature, but
I can well imagine it giving you the screaming willies^H^H^H^H^H hillaries! ;-)

-- John Volan

>                                -- Adam

>(P.S. John, how about we get together and start our own church?  :-)

Dibbs!  I get to be pope first! :-)

--------------------------------------------------------------------------------
--  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.");
--------------------------------------------------------------------------------



  parent reply	other threads:[~1994-10-02 16:41 UTC|newest]

Thread overview: 43+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
1994-09-27 16:52 Mut. Recurs. in Ada9X w/o Breaking Encaps.? (LONG) John Volan
1994-09-27 18:48 ` Mark A Biggar
1994-09-29  1:46   ` John Volan
1994-09-29 13:57     ` Tucker Taft
1994-09-29 17:20       ` Bjarne Stroustrup <9758-26353> 0112760
1994-09-30  1:38         ` Tucker Taft
1994-09-30 12:33           ` Bjarne Stroustrup <9758-26353> 0112760
1994-09-29 18:37       ` John Volan
1994-09-29 19:34         ` David Weller
1994-09-30 22:13           ` John Volan
1994-10-02  3:31             ` Andrew Lees
1994-09-30  1:47         ` Tucker Taft
1994-09-30 13:30           ` John Volan
1994-09-29 18:10     ` R. William Beckwith
1994-10-03  0:33     ` Cyrille Comar
1994-09-28 14:01 ` Norman H. Cohen
1994-09-29  2:12   ` John Volan
1994-09-29 14:01     ` Tucker Taft
1994-09-29 18:37     ` Norman H. Cohen
1994-09-29  9:48   ` Magnus Kempe
1994-09-29 13:10     ` Magnus Kempe
1994-09-29 18:05       ` Tucker Taft
1994-09-30 10:20         ` Mut. Recurs. in Ada9X w/o Breaking Encaps.? Magnus Kempe
1994-09-30 13:22           ` Tucker Taft
1994-10-01  1:24       ` Mut. Recurs. in Ada9X w/o Breaking Encaps.? (LONG) Adam Beneschan
1994-10-01 12:01         ` Magnus Kempe
1994-10-01 18:43         ` Mark A Biggar
1994-10-02 16:41         ` John Volan [this message]
1994-10-02 23:33           ` Matt Kennel
1994-10-03  8:07           ` Mut. Recurs. in Ada9X w/o Breaking Encaps.? Magnus Kempe
1994-10-03 12:14           ` Mut. Recurs. in Ada9X w/o Breaking Encaps.? (LONG) Robert I. Eachus
1994-10-04  2:12             ` R. William Beckwith
1994-10-04 16:00             ` John Volan
1994-10-05 11:42               ` Robert I. Eachus
1994-10-05 21:09               ` Matt Kennel
1994-10-03 20:29           ` Harry Koehnemann
1994-09-29 13:35     ` John Volan
1994-09-30 20:27       ` Norman H. Cohen
1994-10-01  1:47         ` John Volan
1994-10-01 20:44           ` Tucker Taft
1994-10-03 11:29           ` Robert I. Eachus
1994-09-30 22:46       ` Matt Kennel
1994-10-01  2:11         ` 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