Re: Ada GC and a bunch of other stuff

ncohen@watson.ibm.com (Norman H. Cohen)
9 Feb 1996 14:33:03 -0500

          From comp.compilers

Related articles
Possible to write compiler to Java VM? (I volunteer to summarize) seibel@sirius.com (Peter Seibel) (1996-01-17)
Re: Ada GC and a bunch of other stuff hbaker@netcom.com (1996-02-03)
Re: Ada GC and a bunch of other stuff chase@centerline.com (1996-02-09)
Re: Ada GC and a bunch of other stuff ncohen@watson.ibm.com (1996-02-09)
Re: Ada GC and a bunch of other stuff dave@occl-cam.demon.co.uk (Dave Lloyd) (1996-02-13)
Re: Ada GC and a bunch of other stuff hosking@cs.purdue.edu (1996-02-13)
Re: Ada GC and a bunch of other stuff boehm@parc.xerox.com (1996-02-14)
Re: Ada GC and a bunch of other stuff dave@occl-cam.demon.co.uk (Dave Lloyd) (1996-02-16)
Re: Ada GC and a bunch of other stuff hbaker@netcom.com (1996-02-17)
Re: Ada GC and a bunch of other stuff boehm@parc.xerox.com (1996-02-21)
[3 later articles]
| List of all articles for this month |

From: ncohen@watson.ibm.com (Norman H. Cohen)
Newsgroups: comp.compilers,comp.lang.ada
Followup-To: comp.lang.ada
Date: 9 Feb 1996 14:33:03 -0500
Organization: IBM T.J. Watson Research Center
References: 96-01-037 96-02-031
Keywords: GC, performance, design

hbaker@netcom.com (Henry Baker) writes:


|> Ada83 got off on the wrong foot by trying to legislate programming
|> style. There are quite a number of restrictions in Ada that have
|> nothing to do with programming semantics, or safety, or anything
|> substantive. They were put there because someone thought that the
|> result would be more stylistically correct _in their opinion, at that
|> particular point in time_.


To some extent this is certainly true, but I don't think the problem
is as pervasive as Henry suggests, or that it affected the basic
character of Ada 83. There were a few minor annoynances, most of
which were eliminated in Ada 95.


|> For example, there are silly restrictions
|> on the spelling of identifiers that require additional code to check
|> for, and clutter up the manual and the compiler.


The only restrictions on the spelling of identifiers are


      1. A reserved word cannot be used as an ordinary identifier.
      2. An identifier must adhere to the grammar
                  letter { [underline] letter_or_digit }


(In Ada 95, a "letter" is called an "identifier_letter".) I will
guess that Henry is objecting to restriction 2, which disallows
underscores at the beginning, at the end,and adjoining other
underscores. This issue was fiercely debated (far in excess of its
importance) during the Ada 9X project, and it ignited religious
passions both on Henry's side of the issue and on the other side. The
lexical grammar


          letter { [underline] letter_or_digit }


does not clutter up either the manual or the compiler appreciably more
than


          letter_or_underline { letter_or_digit_or_underline }


so this is a silly objection. (The "restriction" falls naturally out of
the lexical grammar rather than by imposing an extra check as Henry
suggests.) Yes, it is arbitrary that Ada disallows ____ := ___ + _____;
while allowing O0O0 = O0O + O000O; but who cares?


|> There used to be
|> silly restrictions on the ordering of certain kinds of declarations,
|> but most of these were dropped in Ada95.


Yes, and they are not missed!


|> I believe that there still
|> are in Ada95 silly restrictions on the ordering of 'private' and
|> 'public' parts of a 'specification' (C++ people: think 'class
|> definition') whose rationale is incomprehensible to a C++ programmer
|> accustomed to putting 'public:' and 'private:' anywhere that is
|> convenient.


Agreed, although Henry's terminology is somewhat misleading. What
Henry describes as a "restriction" is just a consequence of the
grammar for package specifications. One of Ada's strengths is that it
clearly separates those parts of a program constituting a module's
interface from those parts constituting a module's implementation.
This is such a fundamental aspect of the Ada world view that I would
not call the restriction arbitrary. However, it is undeniably based
on methodology, and it undeniably gets in the way on occasion.


|> This last rule may appear to be merely a stylistic rule, with no
|> substantive effect. This is not true, however, since other ordering
|> rules conspire with this one to eliminate the ability to define
|> certain relatively simple types in a single package. By forcing the
|> programmer to utilize a number of subsidiary packages -- whose only
|> purpose is to get around the silly ordering rule -- the original
|> rationale of the ordering rule -- 'prettier programs' -- has now been
|> completely turned on its head. The public/private ordering rule
|> _forces_ the programmer to engage in the very behavior it was meant to
|> prohibit!


It's worse than that. Occasionally you CAN'T use subsidiary packages
in a way in which you would have liked to. In my response to John
Volan last week about mutually dependent types (comp.compilers readers
are referred to comp.lang.ada for this discussion), I would have liked
to have written


      package Persons is


            type Person_Type is tagged private;


            package Doctors is
                  type Doctor_Type is new Person_Type with private;
                  -- ... operations with Doctor_Type and Person_Type parameters
            private
                  type Doctor_Type is new Person_Type with ...; -- ILLEGAL!
            end Doctors;


            -- ... operations with Person_Type and Doctor_Type parameters


      private


            type Person_Type is tagged ...;


      end Persons;


For quite sensible implementation reasons, Ada 95's freezing rules
prevent me from extending Person_Type before its full type declaration
(in the private part of the outer package). This led me to an
intricate workaround involving access discriminants. I would have
much preferred to be able to write


      package Persons is


            type Person_Type is tagged private;


      private


            type Person_Type is tagged ...;


      public -- NOT REALLY AN ADA CONSTRUCT!


            package Doctors is
                  type Doctor_Type is new Person_Type with private;
                  -- ... operations with Doctor_Type and Person_Type parameters
            private
                  type Doctor_Type is new Person_Type with ...;
            end Doctors;


            -- ... operations with Person_Type and Doctor_Type parameters


      end Persons;


--interleaving a private region of the Persons package specification
between two public regions so that Person_Type could be extended in a
visible region while keeping its full declaration private.


Here is a half-baked proposal for Ada 0X: Allow a package to consist
of a sequence of compilation units of the form


      "package" name "(" expression "of" expression ")" "is"
            { declaration }
      [ "private "
            { declaration }
      [ "begin"
            handled_sequence_of_statements ]
      "end" name "(" expression "of" expression ")" ";"


where the expressions are static universal integer expressions. (Read
the construct


        package My_Package (2 of 5) is
              ...
        end My_Package;


as Part 2 of a package consisting of 5 parts.)


The sequence of package parts, in order, forms a declarative region.
The seqeunces of statements are executed during elaboration of the
package. The recommended style is to have each of these compilation
units consist entirely of a visible part or entirely of a private part
possibly accompanied by initialization statements, but in deference to
Henry Baker the language rules will not enforce this. An incomplete
type declaration anywhere within this region can be completed anywhere
within the region. A with clause can name one of the numbered parts
of a declarative region, in which case it provides access to the
visible parts of that and all lower-numbered parts of the package.
Package bodies are still retained in the language for upward
compatibility, but they are superfluous, since they can be modeled as
highest-numbered package parts with no visible declarations. An
object of a given type can only be declared within the scope of a full
declaration for that type.


In one swell foop, this proposal accomplishes the following:


      - It allows arbitrary interleaving of private and public declarations.


      - It answers the old objection that the declarations in the private
          part of a package do not really belong in the package specification,
          since they describe aspects of a package's implementation rather
          than its interface. A package can now be written in three parts:


          package Stacks (1 of 3) is
                type Stack_Type (Capacity: Natural) is private;
                procedure Push (Item: in Integer; Stack: in out Stack_Type);
                procedure Pop (Item: out Integer; Stack: in out Stack_Type);
          end Stacks (1 of 3);


          package Stacks (2 of 3) is
          private
                type Integer_List_Type is array (Positive range <>) of Integer;
                type Stack_Type (Capacity: Natural) is
                      record
                            Top : Natural := 0;
                            Elements : Integer_List_Type (1 .. Capacity);
                      end record;
          end Stacks (2 of 3);


          package Stacks (3 of 3) is
          private
                procedure Push (Item: in Integer; Stack: in out Stack_Type) is
                      ...
                end Push;
                procedure Pop (Item: out Integer; Stack: in out Stack_Type) is
                      ...
                end Pop;
          end Stacks (3 of 3);


          A typical client of package Stacks has a with clause for part 2.
          This allows the client to be compiled before part 3 (what we used to
          call the package body), but allows the client to declare Stack_Type
          objects (because part 2 has full type declaration). A client that
          does not need to create Stack_Type objects can get away with a with
          clause for part 1, thus reducing recompilation requirements should
          the representation of stacks later change.


      - It solves the mutually-dependent-types problem:


          package Doctors (1 of 4) is
                type Doctor_Type is abstract tagged private;
          end Doctors (1 of 3);


          package Patients (1 of 4) is
                type Patient_Type is abstract tagged private;
          end Patients (1 of 3);


          with Patients (1 of 4);
          package Doctors (2 of 4) is
                -- ...operations with Doctor_Type and Patient_Type parameters
          end Doctors (2 of 4);


          with Doctors (1 of 4);
          package Patients (2 of 4) is
                -- ...operations with Patient_Type and Doctor_Type parameters
          end Patients (2 of 4);


          package Doctors (3 of 4) is
          private
                type Doctor_Type is [full declaration];
          end Doctors (3 of 4);


          package Doctors (4 of 4) is
          private
                -- ... subprogram bodies
          begin
          end Doctors;


          package Patients (3 of 4) is
          private
                type Patient_Type is [full declaration];
          end Patients (3 of 4);


          package Patients (4 of 4) is
          private
                -- ... subprogram bodies
          begin
          end Patients;


          (Package parts are a generalization of the "package abstract" John
          Volan has proposed to solving the mutually-dependent-types problem.)


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


--


Post a followup to this message

Return to the comp.compilers page.
Search the comp.compilers archives again.