[comp.lang.ada] Ada language revision

SALLEN%LOCK.SPAN@STAR.STANFORD.EDU (Stanley Roger Allen, AdaDude) (11/14/88)

	Well, time is pressing on and the review has begun for
analyzing anew changes that should be made to the Ada language.
Through a variety of sources, a number of not-very-bright statements
have come to our attention concerning "improvements" to the Ada
language that should be "easily incorporated" into the the 1994
revision.

	A lot of these people are certainly driven by nothing more
sinister than the "feature junkie" complex (cf. Dijkstra's Turing
Award lecture, 1972).  What makes a lot of these suggestions dangerous
is more that just a lack of appreciation for the language design and
structure.  We are also seeing a deep misapprehension of what the
goals of the Ada program are to begin with.  We are not trying to
create a research engine, or a summation of the latest programming
language paradigms, or a fault-tolerant distributed operating system, 
etc.  Those who are to make decisions about the future of the Ada 
language need discover what exactly we *are* trying to create.

	To give a one-line answer to this question would be to defeat
the purpose of this missive.  I am proposing that anyone who wishes to
make suggestions for improving the language, adding new features,
deleting language elements, or change the organization of the language
(even in ways that may seem trivial) should first do their homework.
There is a specific body of knowledge that you should possess when
approaching this topic.  Have you read the Steelman document and/or
its predecessors?  (Do you even know what the Steelman document is?) 
Have you read the "Rationale for the Design of the Ada Language"?  Do
you understand the type system of the Ada language?  Have you been
looking through the megabytes of textual commentaries that have been
accumulating since the beginning of the Ada program?  Does the LRM
still confuse you? 

	Perhaps there should be a "required reading list" and
"qualifying exams" for Ada language maintainers.  Perhaps there is; I
don't know.  Jean Ichbiah says that many languages previous to Ada
followed a three-step process for their creation: "shoot, aim, think".
Ada is among the languages that reversed the process, which is one of
the reasons for the great success it has become.  In maintaining the 
language, thinking should also come first.  Part of that thinking is 
going back to previous thinking and absorbing it.  Any other path is 
pure hubris.

					Stanley Allen
					allen@star.stanford.edu

rivers@seismo.CSS.GOV (Wilmer Rivers) (11/16/88)

[Do not eat this line under penalty of law.]

   This is a somewhat edited version of a message I sent by E-MAIL
to SALLEN%LOCK.SPAN@STAR.STANFORD.EDU (Stanley Roger Allen) in response
to message <8811141420.AA01652@ajpo.sei.cmu.edu>.  I shall not re-post
any excerpts from his original article, but as I interpreted it he
wanted to make 2 major complaints : (1) many or most changes that are
being suggested to Ada are not adequately thought out before they are
proposed, and (2) any changes that would deviate from the original
intent of Ada's goals should be eschewed.  Although the first point
may well be correct, I should like to take mild exception to the
second one, and I am posting these remarks publicly in order to en-
courage further discussion of this issue via this newsgroup.

   The article seems to suggest that any changes to Ada should be re-
stricted to refining the grand design that was set into motion long
ago, rather than accommodating any changes that would involve a new
direction for the language.  You can certainly build a strong case for
that.  ("Here's what Ada is supposed to do, and if you want to do some-
thing else, then come up with a different language, just don't call it
Ada.")  However, proponents of more drastic changes also have a point.
Suggesting that all changes should be confined to moving from Steelman
to TitaniumMan (or ReinforcedConcreteMan, or whatever) may be too rigid.
(No pun intended, but actually the concept of rigidity is appropriate
here.)  This concept of minimal evolution reminds me of the member of
the board of directors of the Metro system here in D.C. who recently
dismissed commuters' pleas for more farecard machines in certain subway
stations by noting that introducing more machines would "interfere with
the aesthetic purity of the design" of the stations.  He's right, but
(1) commuting patterns change; (2) the farecard machines have turned out
to be less reliable than they were in the original "aesthetically pure"
design; and (3) assuming you don't want the subway stations to serve as
museums or cathedrals, what counts is not so much their architectural
splendor as how easy they make it to catch a train.  So it is with pro-
gramming languages.  (1) Programming has changed in recent years [and of
course Ada is partly responsible for that]; (2) some features of Ada
haven't *really* worked so well as the designers had intended; and (3)
whether or not the LRM is the best thought-out set of rules and specifi-
cations since the U.S. constitution is less important than whether pro-
grammers can use Ada to get their job done.  Apparently, some of them
think they can't, so they want some changes that aren't consistent with
what Steelman (and maybe even Strawman) thought Ada was supposed to do.
Is that so terrible?  The dogmatic attitude of "If it's inconsistent
with all the great effort that we've put into Ada, then it's heresy and
we musn't do it" may not be the best one for revising the language.
Sometimes it's necessary (or at least desirable) to make fundamental
changes ab initio, even if they are in conflict with what you originally
had in mind.  For example, if someone wants a language that does some of
the things that were cited in the original posting as contrary to the
goals of Ada, then is it so unthinkable for him to suggest that the new
language he needs should nevertheless still be Ada?  Saying "Nope, that
definitely isn't what Ada is all about," really just begs the issue.  An
appropriate response would be, "Maybe Ada wasn't about that originally,
but why shouldn't it be about that now?"  You shouldn't automatically
legislate against progress by saying that the goal of the language is
cast in stone (or straw, wood, tin, iron, steel, titanium, reinforced
concrete, ...).

   Well, that's my own mild flame.  In summary, I am arguing that langu-
age design purists shouldn't be allowed to use the obvious necessity for
considering very carefully any proposed changes to the LRM as justifi-
cation for outlawing a priori any changes in the *intent* of the langu-
age itself.  As I said above, a strong case can in fact be made for that
attitude, but personally I don't think making the language's goals sac-
rosanct is in the best interest of the programming community.

			    Wilmer Rivers (rivers@beno.CSS.GOV)
			    Teledyne Geotech


[I suppose I should add the standard disclaimer stating that my own
views and those of my employers may differ, but actually I doubt that
the company cares very much about this issue one way or the other, and
they would probably perfer that I didn't spend any time caring about
it either.]

billwolf@hubcap.clemson.edu (William Thomas Wolfe,2847,) (11/17/88)

   In view of the recent discussions re: appropriateness of revisions, I'm 
   hereby submitting the revisions I think appropriate for Ada 9X for general
   discussion and/or flamage:

      1) The assignment operator should be available for overloading
         as part of an ADT specification (i.e., a limited private type 
         which is enclosed within a (usually generic) package).  Currently, the
         closest we can come is to define an ASSIGN procedure.  Unfortunately,
         this is not consistent with the use of := for other object types, and
         worse yet, the ASSIGN procedure is not invoked during the evaluation of
         in parameters, making it impossible to achieve anything other than a
         shallow copy of a user-defined ADT which is used as a value parameter,
         the disastrous implications of which should be readily apparent.

      2) Similarly, there is no provision for defining the DESTROY procedure
         over an abstract data type such that UNCHECKED_DEALLOCATION is required
         to invoke it.  Again, we have inconsistency with the predefined 
         objects, and there are unfortunate implications for space efficiency.

      3) The rule that a limited private type cannot be a direct component of 
         another limited private type should be repealed.  This makes it hard
         to use one ADT as a building block in the construction of higher-level
         ADTs.  The standard workaround is to use an intervening pointer, with
         negative implications for time and space efficiency upon each access.

      4) It should be possible to overload generic packages with differing 
         generic parameter structures.  For example, suppose I have two
         generic linked list requirements: sometimes I need the ability to
         INPUT and OUTPUT the list to a file, and sometimes I don't.  If I
         can't overload the package with differing generic parameter structures,
         I'll have to include the procedures INPUT (LINKED_OBJECT) and 
         OUTPUT (LINKED_OBJECT) in every instantiation of a linked list;
         even if I have no intention of ever calling the INPUT and OUTPUT 
         procedures for this particular type of linked list.  Result: more work
         on my part to define unnecessary INPUT and OUTPUT procedures which will
         never be called, and possibly an unnecessarily large body of 
         instantiated code which contains code to handle procedures that I will
         never call. 

      5) The rule that functions must have only in parameters should be 
         repealed.  Data structures which are history-sensitive, such as tree
         structures which secretly keep a "current item" pointer in order to
         speed up groups of requests which all involve the same item, will
         subtly change as a result of calls to the Boolean function ITEM_EXISTS;
         this forces us to use an intervening pointer in order to implement
         such a function with only in parameters, and suffer the resulting time 
         and space penalties upon each and every access to the structure. 
 
      6) Exceptions should be capable of being passed as parameters.  Currently,
         it is not possible to write a function ASSERT which takes a Boolean
         expression and an exception, and raises the exception if the expression
         turns out to be false.  The workaround is to enclose every call to 
         ASSERT in a local block, with an exception handler specifying that
         the desired exception should be raised in response to the exception
         Assertion_Failed.

      7) Arrays should be initializable via named association.  It is very 
         tedious to write out 37 Falses simply in order to initialize the
         38th element of a Boolean array to True before I can finally specify 
         that all other elements of the array are False. 

       8) Record types should have the attributes NUMBER_OF_FIELDS, 
          FIELD_NAME (Field Number), and FIELD_TYPE (Field Number).  Not having
          these attributes prevents the construction of a generic report
          generator which will accept a record type as a generic parameter,
          and provide a function GENERATE_REPORT which, given a file of those
          records, will automatically generate a report in which the column
          headers are labeled with the field names (with spaces substituted for
          underscores), and automatically laid out across the page with the
          appropriate spacing between columns.  Assuming the availability of an
          appropriate system call, the name of the source file could even be 
          used as the report title.   But without being able to read that record
          descriptor, the implementation of such a generic report generator is
          very hard to achieve in any reasonably clean way. 


   Well, there they are.   Now where was that fireproof outfit...?


                                                   Bill Wolfe

                                             wtwolfe@hubcap.clemson.edu

leake@cme-durer.ARPA (Stephe Leake) (11/17/88)

In reference to Stanley Allen's comments in message
<8811141420.AA01652@ajpo.sei.cmu.edu>, I agree completely.  However,
he did not give adequate references for me to go out and buy the
reading material he suggested, and I have the impression they are not
available in my corner bookstore. It seems to me that this forum is an
excelent place for us novices to propose changes, giving him and
others more knowledgeble a chance to spread some education. So, I am
responding to Wolfe's list of changes with my own opinions, and I hope
others do the same.

Note to future suggestors: please include the LRM section and
paragraph when suggesting a change to a specific rule.

In article <3563@hubcap.UUCP> billwolf@hubcap.clemson.edu (William
Thomas Wolfe,2847,) writes:

	 1) The assignment operator should be available for
	    overloading as part of an ADT specification...

Hear Hear! Right on! (and other assorted agreeable noises)

	 2) Similarly, there is no provision for defining the DESTROY
	    procedure over an abstract data type such that
	    UNCHECKED_DEALLOCATION is required to invoke it...

This needs clarification; what does a DESTROY procedure do that
UNCHECKED_DEALLOCATION doesn't?

	 3) The rule that a limited private type cannot be a direct
	    component of another limited private type should be
	    repealed...

What rule are you refering to? I have a Commented_IO package which
defines a limited private FILE_TYPE, which includes as a component
Text_IO.FILE_TYPE (also limited private). It compiles just fine.

	 4) It should be possible to overload generic packages with
	    differing generic parameter structures....

This sounds good. Currently, a better work-around is to have two
packages, both using a common lists sub-package.

	 5) The rule that functions must have only in parameters
	    should be repealed....

I have often wanted to do this myself, but I usually (not always) find
that a procedure ends up making more sense. In general, I find that
the restrictions Ada imposes usually lead to better code. (See my
personal gripes below for exceptions to this.)

	 6) Exceptions should be capable of being passed as
	    parameters....

What's wrong with a small if statement? Personally, I would like to
have an EXCEPTION_IO that would let me print the name of an exception.

	 7) Arrays should be initializable via named association...

According to LRM 4.3.2 (3), they are.

	 8) Record types should have the attributes NUMBER_OF_FIELDS,
	    FIELD_NAME (Field Number), and FIELD_TYPE (Field Number)....

This sounds good, but I suspect it would be difficult to handle
[limited] private types and variant records. Does NUMBER_OF_FIELDS
return the number for the current discriminant, or something else? You
can't expect the compiler to do _everything_ for you!

Here are a couple restrictions that I would like relaxed:

	9) LRM 10.2 (5) states that the simple names of all subunits
that have the same ancestor library unit must be distinct. This means
I can have tasks named ROBOT.PLANNER.MAIN_TASK and
ROBOT.TRAJECTORY.MAIN_TASK, but only if the task bodies are not
separately compiled; then the simple name MAIN_TASK must be changed.
This seems contrary to the intent of Ada naming. If the rule where
changed to "the simple names of all subunits that have the same
_parent_ unit must be distinct", things would be nicer.

	10) LRM 4.3.2 (6) says if I have an array aggregate with named
association and an others clause, it must be an actual parameter or
function result; ie, _not_ an object initalization. This prevents me
from declaring an object with an anonymous array type and initializing
it; which is exactly the correct thing to do for a state table in a
lexical analyzer. I do not want a named array type, since I do not
want any other state tables; I only need one.

	11) LRM 8.5 (2) lists the things that can be renamed. I would
like to add enumerals. I like to rename some things from a package
(usually with the same name) to make them visible, instead of "use"ing
the whole package; this makes it clear I am _not_ using the whole
package. Currently, to make an enumeral visible, I must declare a
derived type, which means I have to use explicit type conversions.

Well, that's probably enough for now.

Stephe Leake 	(301) 975-3431 		leake@cme.nbs.gov
National Institute of Standards and Technology
(formerly National Bureau of Standards)
Rm. B-124, Bldg. 220
Gaithersburg, MD  20899

rfg@nsc.nsc.com (Ron Guilmette) (11/18/88)

In article <3563@hubcap.UUCP> wtwolfe@hubcap.clemson.edu writes:
>
>   In view of the recent discussions re: appropriateness of revisions, I'm 
>   hereby submitting the revisions I think appropriate for Ada 9X for general
>   discussion and/or flamage:

Well, since somebody else started this ball rolling, I guess it might be safe
to do a little Ada bashing and launch off into a jihad of my own.

>      3) The rule that a limited private type cannot be a direct component of 
>         another limited private type should be repealed...

I have some problems with limited private types too.  Specifically, if such
types are really only accessable through a "limited" functional interface,
then why shouldn't we be able to declare such types in the public part of
a package and then defer the full declaration until the package body?  Why?
Well, I'll tell you why.  It seems to me that it is because of Ada's silly
specification of parameter passing conventions, where the implementor gets
to decide if he/she wants to pass any given scalar type object using
value-result.  This should also be repealed.  All parameters should be passed
by reference.  Period.  Then programmers would never have to guess about
implementation semantics and the compiler would never have to know what the
real implementation of a given limited private type was until the package
body was being compiled.

>      6) Exceptions should be capable of being passed as parameters.

I agree completely, but I would go much further and say that any category of
run-time (not compile-time) entity which can be represented by an identifier
(including exceptions and record field names, but not generic units) should
be "passable" as parameters.  Further, I think that *all* entities which
can be designated by an identifier (including exceptions, record field names,
and generic units) should be "passable" as generic (instantiation) parameters.

>      7) Arrays should be initializable via named association.

If Ada only had "classes" (a la Simula & C++) we could trash a whole lot of
specialized convoluted syntax and semantics having to do with initialization
and constructors also.

>       8) Record types should have the attributes NUMBER_OF_FIELDS, 
>          FIELD_NAME (Field Number), and FIELD_TYPE (Field Number).  Not having
>          these attributes prevents the construction of a generic report
>          generator which will accept a record type as a generic parameter,
>          and provide a function GENERATE_REPORT which, given a file of those
>          records, will automatically generate a report in which the column
>          headers are labeled with the field names...

OK, but how do you number the fields in a variant record?

-- 
Ron Guilmette
National SemiConductor, 1135 Kern Ave. M/S 7C-266; Sunnyvale, CA 94086
Internet: rfg@nsc.nsc.com   or   amdahl!nsc!rfg@ames.arc.nasa.gov
Uucp: ...{pyramid,sun,amdahl,apple}!nsc!rfg

tynor@pyr.gatech.EDU (Steve Tynor) (11/19/88)

In article <733@marvin.cme-durer.ARPA> leake@cme-durer.ARPA (Stephe Leake) writes:
>What's wrong with a small if statement? Personally, I would like to
>have an EXCEPTION_IO that would let me print the name of an exception.

Here, here, etc.  I once worked with the Telesoft (?) compiler on an Eclipse
that had a package allowing you to find out what the current exception was.
It helped out immensely during debugging:

    ...
    exception
       when others =>
	   text_io.put_line ("Opps! exception " & CURRENT_EXCEPTION'IMAGE &
			      " in procedure XXX.");
	   raise;
    end XXX;

Unfortunately, I now use VAX Ada and Alsys, so I can't do this.  

=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
Progress means replacing something wrong with something more subtly wrong.
                     
    Steve Tynor
    Georgia Tech Research Institute
    tynor@gitpyr.gatech.edu

rfg@nsc.nsc.com (Ron Guilmette) (11/19/88)

In article <733@marvin.cme-durer.ARPA> leake@cme-durer.ARPA (Stephe Leake) writes:
>..Personally, I would like to
>have an EXCEPTION_IO that would let me print the name of an exception.

Howza 'bout allowing:

	MY_EXCEPTION'IMAGE

-- 
Ron Guilmette
National SemiConductor, 1135 Kern Ave. M/S 7C-266; Sunnyvale, CA 94086
Internet: rfg@nsc.nsc.com   or   amdahl!nsc!rfg@ames.arc.nasa.gov
Uucp: ...{pyramid,sun,amdahl,apple}!nsc!rfg

stt@inmet (11/21/88)

"Official" revision requests for Ada will ultimately have
to be sent to "ada9x@ajpo.sei.cmu.edu" following
a detailed format similar to language comments
as specified in the back of the Ada LRM, but with
many more standard paragraphs, including
"!keywords", "!summary", "!specific requirement/solution criteria", etc.
The primary emphasis is to state *requirements* which are currently
felt to be unanswered by Ada, rather than specific solutions.
The official revision request format will probably be announced soon.

It's pretty easy to indulge in Ada bashing, or Fortran bashing,
or Pascal bashing, etc.  However, the ada9x effort will probably
be most responsive to carefully argued points.  The following
2 points by <billwolf@hubcap.UUCP> would be easier to understand
if they identified the LRM paragraph of the mentioned "rule".
As far as I know, no such rules exist.

>>  3) The rule that a limited private type cannot be a direct component of 
>>     another limited private type should be repealed.  

Perhaps the issue is that non-limited types may not have components
of limited types?  (I agree this is annoying, though defensible.)

>>  7) Arrays should be initializable via named association.  It is very 
>>     tedious to write out 37 Falses simply in order to initialize the
>>     38th element of a Boolean array to True before I can finally specify 
>>     that all other elements of the array are False. 

Named aggregates are legal to initialize arrays.  Perhaps the issue
is the use of "named" notation in conjunction with "others =>".
This is never permitted in places where implicit array subtype
conversion (aka "sliding") is legal because there is no way of knowing what
is the first element of the aggregate (it may be one of the named
elements, or it may be one of the "others").
To avoid this problem, a qualified expression may be used,
specifying the subtype of the array aggregate explicitly,
which implies the low and high bounds.

Generally I agree with the spirit, if not the details, of these
requests.  But to be effective, they must be as formally
and carefully stated as possible.

Tucker Taft   stt@inmet.inmet.com; ...!uunet!inmet!stt
Intermetrics, Inc.
Cambridge, MA  02138

leake@cme-durer.ARPA (Stephe Leake) (11/22/88)

In article <7882@nsc.nsc.com> rfg@nsc.nsc.com (Ron Guilmette) writes
(among other things):

>   I have some problems with limited private types too.  Specifically, if such
>   types are really only accessable through a "limited" functional interface,
>   then why shouldn't we be able to declare such types in the public part of
>   a package and then defer the full declaration until the package body?

What would this gain? Do you have any specific examples where this
would have improved the readability or functionality of an
application? Let's not just suggest changes because they "sound good".
Let's put some thought into it, including concrete examples.

   ... I would go much further and say that any category of
   run-time (not compile-time) entity which can be represented by an identifier
   (including exceptions and record field names, but not generic units) should
   be "passable" as parameters.  Further, I think that *all* entities which
   can be designated by an identifier (including exceptions, record field names,
   and generic units) should be "passable" as generic (instantiation) parameters.

Again, why? What would we gain, what would we lose?

   >      7) Arrays should be initializable via named association.

According to LRM 4.3.2 (3), they are. (Doesn't anybody read the manual?)

   If Ada only had "classes" (a la Simula & C++) we could trash a whole lot of
   specialized convoluted syntax and semantics having to do with initialization
   and constructors also.

What convoluted syntax? There is _one_ construct; the aggregate. It is
a _very_ powerful construct, and I consider it one of the best
features of Ada. Perhaps you could give us an example of how Simula or
C++ would do something that an aggregate can't do.

Let's try to keep the discussion concrete, so we can come up with real
suggestions to the review commitee, not just a letter to Santa Claus.

Stephe Leake 	(301) 975-3431 		leake@cme.nbs.gov
National Institute of Standards and Technology
(formerly National Bureau of Standards)
Rm. B-124, Bldg. 220
Gaithersburg, MD  20899

dd@sei.cmu.edu (Dennis Doubleday) (11/23/88)

In article <739@marvin.cme-durer.ARPA> leake@cme-durer.ARPA (Stephe Leake) writes:
>In article <7882@nsc.nsc.com> rfg@nsc.nsc.com (Ron Guilmette) writes
>>   I have some problems with limited private types too.  Specifically, if such
>>   types are really only accessable through a "limited" functional interface,
>>   then why shouldn't we be able to declare such types in the public part of
>>   a package and then defer the full declaration until the package body?
>
>What would this gain? Do you have any specific examples where this
>would have improved the readability or functionality of an
>application? Let's not just suggest changes because they "sound good".
>Let's put some thought into it, including concrete examples.

There is a VERY good reason for it, if you're at all concerned about
portability.  The declaration of a limited private type is an
IMPLEMENTATION decision.  It doesn't belong in the specification, it
belongs in the body.  If I'm trying to export some abstract data type
from a package, I'd like to have a specification that could be moved,
intact, from one machine to another.  Only the body should need
changing.  However, since I must give the full declaration of the type
in the private part of the spec instead of in the body, it may be that
I will have to change that part of the spec if I want to port the
package to a machine which requires a different implementation of the
type. 

Why does your post sound so hostile?  How do you know that Ron hasn't
put any thought into his suggested changes?

Dennis Doubleday                       dd@sei.cmu.edu
Software Engineering Institute         (412)268-5873
Carnegie Mellon University
Pittsburgh, PA 15213

tynor@pyr.gatech.EDU (Steve Tynor) (11/24/88)

In article <7796@aw.sei.cmu.edu> dd@sei.cmu.edu (Dennis Doubleday) writes:
>
>In article <739@marvin.cme-durer.ARPA> leake@cme-durer.ARPA (Stephe Leake) writes:
>>In article <7882@nsc.nsc.com> rfg@nsc.nsc.com (Ron Guilmette) writes
>>>   then why shouldn't we be able to declare such types in the public part of
>>>   a package and then defer the full declaration until the package body?

>>What would this gain? Do you have any specific examples where this

>portability.  The declaration of a limited private type is an
>IMPLEMENTATION decision.  It doesn't belong in the specification, it
>belongs in the body.  If I'm trying to export some abstract data type

Here, here. I think the Modula 2 compromise of requiring 'opaque' types to be
pointers is adequate. This way there is enough information supplied in the
specification for code generation in client packages, but the implementation 
details are not broadcast.  Sure, the code may be slightly less efficient
(since you're forced to use a pointer), but I've rarely run into a situation
where I've wanted to create an ADT where a pointer (ok, ok, 'access
type') wasn't the natural representation anyway...

=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
Progress means replacing something wrong with something more subtly wrong.
                     
    Steve Tynor
    Georgia Tech Research Institute
    tynor@gitpyr.gatech.edu

pattis@june.cs.washington.edu (Richard Pattis) (11/24/88)

In article <6843@pyr.gatech.EDU>, tynor@pyr.gatech.EDU (Steve Tynor) writes:
> Here, here. I think the Modula 2 compromise of requiring 'opaque' types to be
> pointers is adequate. This way there is enough information supplied in the
> specification for code generation in client packages, but the implementation 
> details are not broadcast.  Sure, the code may be slightly less efficient
> (since you're forced to use a pointer), but I've rarely run into a situation
> where I've wanted to create an ADT where a pointer (ok, ok, 'access
> type') wasn't the natural representation anyway...
> 
>     Steve Tynor
>     Georgia Tech Research Institute
>     tynor@gitpyr.gatech.edu

  As someone who has taught Modula-2 in introductory courses for 4 years (4
times a year) I've voted with my feet and switched to Ada.  Private types are
one reason.  While opaque types do allow for easier portability, and a link
time decision of which imlementation to use, there are some drawbacks.

  For teaching, the concept of a protected object is important and is easy to
motivate.  But by requiring students to learn about dynamic allocation and
deallocation to implement such a type, Modula-2 makes it very hard for me to
intoduce this concept early.  Also, the newest M-2 standard (at least that I
have seen) proposes to restrict opaque types to pointer only, disallowing me
to define an opaque cursor that in one instance must be implement by integer
that refers to some location in an array.

  Also, there are all sorts of problems with initialization/finalization in
Modula-2's opaque types.  Try writing a complex number type and functional
versions of the standard arithmetic operators, including garbage collection.

  Finally, if I recall my Ada correctly, one can use access types in Ada to
implement private types that are equivalent to Modula-2's opaque types, at
least with regard to portability problems residing in package bodies.  I
believe Cohen's book had a discussion of this use of access types in the
private parts of packages.

billwolf@hubcap.clemson.edu (William Thomas Wolfe,2847,) (11/24/88)

From article <733@marvin.cme-durer.ARPA>, by leake@cme-durer.ARPA (Stephe Leake):
> In article <3563@hubcap.UUCP> billwolf@hubcap.clemson.edu (William
> Thomas Wolfe,2847,) writes:
> 
> 	 2) Similarly, there is no provision for defining the DESTROY
> 	    procedure over an abstract data type such that
> 	    UNCHECKED_DEALLOCATION is required to invoke it...
> 
> This needs clarification; what does a DESTROY procedure do that
> UNCHECKED_DEALLOCATION doesn't?

      Consider an ADT which contains pointers to substructures.
      A user declares an access type pointing to an instance of your
      ADT, and uses UNCHECKED_DEALLOCATION to destroy that instance
      after finishing with it.  UNCHECKED_DEALLOCATION will not 
      recursively chase down and free up what might constitute 
      over 99% of the space occupied by the ADT.   Similarly, if your
      ADT uses another ADT in its implememtation, your DESTROY procedure
      will include a call to the DESTROY procedure of the sub-ADT,
      but UNCHECKED_DEALLOCATION will remain oblivious to the method
      which must be used to properly destroy the sub-ADT.

> 	 8) Record types should have the attributes NUMBER_OF_FIELDS,
> 	    FIELD_NAME (Field Number), and FIELD_TYPE (Field Number)....
> 
> This sounds good, but I suspect it would be difficult to handle
> [limited] private types and variant records. Does NUMBER_OF_FIELDS
> return the number for the current discriminant, or something else? 

      Generally, what I would like to do is be able to read everything
      about that record type that is contained in the type's description.
      We have attributes that allow us to know everything about an integer
      type, fixed type, float type, etc; we can tell what the bounds 
      of an array are, but we can't find out much of anything about records.
      ('FIRST_BIT, which tells us how far into the first storage unit 
      occupied by the record we have to go in order to find the first bit 
      of the record, and 'POSITION, which tells us how far past the first 
      storage unit occupied by the record we have to go in order to find 
      the specified component of the record, are the only attributes 
      pertaining specifically to the record)   Also, FIELD_TYPE was
      an error; I meant to say FIELD (Field Number), which would allow
      me to loop through the fields of a given record without knowing
      the names of the fields at compile time.
 
> Here are a couple restrictions that I would like relaxed:
> 
> 	10) LRM 4.3.2 (6) says if I have an array aggregate with named
> association and an others clause, it must be an actual parameter or
> function result; 

      This is what I meant about initializing arrays.  Thanks!

firth@sei.cmu.edu (Robert Firth) (11/26/88)

In article <6843@pyr.gatech.EDU> tynor@pyr.UUCP (Steve Tynor) writes:
>In article <7796@aw.sei.cmu.edu> dd@sei.cmu.edu (Dennis Doubleday) writes:
>>  The declaration of a limited private type is an
>>IMPLEMENTATION decision.  It doesn't belong in the specification, it
>>belongs in the body.  If I'm trying to export some abstract data type
>
>Here, here. I think the Modula 2 compromise of requiring 'opaque' types to be
>pointers is adequate. This way there is enough information supplied in the
>specification for code generation in client packages, but the implementation 
>details are not broadcast.

And Ada provides exactly that facility, in almost exactly the same way.
See [RM 3.8.1(3)].

Sigh.

[On the other hand, whoever
invented that BLOODY STUPID
rule about appended material
having to be at least as long
as quoted material was A PEA
BRAINED FORNICATING MORON.
]

leake@cme-durer.ARPA (Stephe Leake) (11/29/88)

In article <3656@hubcap.UUCP> billwolf@hubcap.clemson.edu (William Thomas Wolfe,2847,) writes:

	 Consider an ADT which contains pointers to substructures.
	 A user declares an access type pointing to an instance of your
	 ADT, and uses UNCHECKED_DEALLOCATION to destroy that instance
	 after finishing with it.  UNCHECKED_DEALLOCATION will not 
	 recursively chase down and free up what might constitute 
	 over 99% of the space occupied by the ADT.   Similarly, if your
	 ADT uses another ADT in its implememtation, your DESTROY procedure
	 will include a call to the DESTROY procedure of the sub-ADT,
	 but UNCHECKED_DEALLOCATION will remain oblivious to the method
	 which must be used to properly destroy the sub-ADT.

I see. Currently, the ADT author must provide a Destroy procedure, and
hope that users of the ADT call it as needed. So it would be nice if
the compiler would enforce this. This doesn't sound to bad; we just
need to add a generic parameter to UNCHECKED_DEALLOCATION (LRM 13.10.1):

generic
    type OBJECT is limited private;
    type NAME is access OBJECT;
    with procedure DESTROY (Y : in OBJECT) is <>;
procedure UNCHECKED_DEALLOCATION (X : in out NAME);

With a default definition of DESTROY declared in Standard, defining
UNCHECKED_DEALLOCATION this way would not break any current Ada
program that uses it. There is still a slight problem; if the
appropriate DESTROY procedure is not visible at the time of
instantiation, we lose.

Stephe Leake 	(301) 975-3431 		leake@cme.nbs.gov
National Institute of Standards and Technology
(formerly National Bureau of Standards)
Rm. B-124, Bldg. 220
Gaithersburg, MD  20899