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