Version 1.4 of ais/ai-00262.txt

Unformatted version of ais/ai-00262.txt version 1.4
Other versions for file ais/ai-00262.txt

!standard 13.13.2 (31)          01-02-15 AI95-00262/01
!standard 13.13.2 (34)
!class amendment 01-02-15
!status work item 01-02-15
!status received 01-02-15
!priority Medium
!difficulty Hard
!subject Access to private units in the private part
!summary
!problem
The private part of a package includes part of the implementation of the package. For instance, the components of a private type may include handles and other low-level data structures.
Ada 95 provides private packages to organize the implementation of a subsystem. Unfortunately, these packages cannot be used in the private part of a public package - the context clause for the private package is illegal.
This makes it difficult to use private packages to organize implementation details of a subsystem.
For example, Claw puts most of the Win32 interface details into a set of private packages. However, the inability to use the contents of those packages in private parts meant that various workarounds had to be used:
Some types were moved to the ultimate parent package (for instance,
all of the handle types);
Many parameters and constants were declared to be of predefined types,
so that the predefined types could be used in the private part (thus losing the benefits of strong typing);
Initializations of components were done in an Initialize routine in the
package body (so that the constants declared in the private packages could be used).
All of this bending of the design was necessary because private packages could not be used in the private part of a public package.
!proposal
(* Either "with private", or a separate compilation scheme for private parts; see appendix for rough proposals of each *)
!discussion
!example
!ACATS test
!appendix

From: Randy Brukardt [Randy@RRSoftware.Com]
Sent: Wednesday, February 14, 2001 1:54 PM

A recent discussion on comp.lang.ada proposed a "with private" context
clause, which would allow the withed entity to be used only in the private
part of a package.

The primary benefit of such a feature is that it would allow the use of
private packages in the private part of a public package. This is currently
impossible, and it forces reorganization of packages.

For instance, originally in Claw we put the low-level Win32 interface in a
series of private packages. However, these packages cannot be accessed in
the private part of the public types. That means that either we had to avoid
strong typing in the low-level interface, or abandon the private package
structure.

For instance, a possible image list package would look like:

    package Claw.Low_Level_Image_Lists is
        type HImage_List is new DWord;
        type IL_Flags is new UInt;
        ILR_DEFAULTCOLOR : constant IL_Flags := 16#0000#;
        ILR_MONOCHROME   : constant IL_Flags := 16#0001#;
         ...
        type Image_Kind_Type is (Bitmap, Icon, Cursor);
        for Image_Kind_Type use (Bitmap => 0, Icon => 1, Cursor => 2);

        function Image_List_Load_Image (
                  Name     : in Claw.Win32.LPCStr;
                  Width    : in Claw.Int;
                  Image_Kind : in Image_Kind_Type;
                  Flags    : in IL_Flags) return HImage_List;
        pragma Import (StdCall, Image_List_Load_Image,
                  "ImageList_LoadImageA");

          ...
    end Claw.Low_Level_Image_Lists;

    with Claw.Low_Level_Image_Lists; -- Illegal!
    package Claw.Image_List is
       type Image_List_Type is tagged private;
       procedure Load_Image (Image_List : in out Image_List_Type;
                             Image : in String;
			     Monochrome : in Boolean := False);
         ...
    private
       type Image_List_Type is tagged record
	Handle : Claw.Low_Level_Image_Lists.HImage_List;
            Flags : Claw.Low_Level_Image_Lists.IL_Flags;
              ...
       end record;
    end Claw.Image_List;

We ended up moving things to the private part of the parent (Claw) [which
makes it very large], eliminating some of the strong typing (since users
don't access this code, it only makes our job harder), and not bothering
with the private packages in the first place (putting the entire contents
into the private part of the Image_List package; but of course that mixes up
the high-level and low-level code).

----

I haven't yet looked at the visibility ramifications of such a feature, but
I will do so if there is sufficient interest in working out a full proposal.

****************************************************************

From: dewar@gnat.com
Sent: Wednesday, February 14, 2001 4:50 PM

<<The primary benefit of such a feature is that it would allow the use of
private packages in the private part of a public package. This is currently
impossible, and it forces reorganization of packages.>>

I think it has a much more significant benefit, which is that it makes
it easier to separate the public and private part into separate files,
where the private part has multiple implementations. We have often needed
that capability, and in fact on our enhancement list for GNAT is to allow
the private part to be in a separate file.

****************************************************************

From: Pascal Leroy [pleroy@rational.com]
Sent: Thursday, February 15, 2001 2:01 AM

> A recent discussion on comp.lang.ada proposed a "with private" context
> clause, which would allow the withed entity to be used only in the private
> part of a package.

I agree that this would be a very useful thing to have.  There is another
benefit, in addition to the interaction with private children: by making a
with clause private, you ensure that in the course of maintenance it won't
be used to write declarations in the visible part, i.e., the stuff in the
withed unit won't be reexported.

Moreover, it seems quite easy to (1) specify in RM terms and (2) implement.

A much better usefulness/complexity ratio than extensible enums, if you ask
me.

****************************************************************

From: dewar@gnat.com
Sent: Thursday, February 15, 2001 12:15 PM

I very much agree with this asessment!

****************************************************************

From: Tucker Taft
Sent: Thursday, February 15, 2001 8:57 AM

Randy Brukardt wrote:
>
> A recent discussion on comp.lang.ada proposed a "with private" context
> clause, which would allow the withed entity to be used only in the private
> part of a package.
>
> The primary benefit of such a feature is that it would allow the use of
> private packages in the private part of a public package. This is currently
> impossible, and it forces reorganization of packages.

This is not a trivial change.  Currently, private children are *never*
needed at compile-time of public specs (ignoring macro expansion
requirements related to generics and inlines, of course!).  This
allows a strong physical separation between the public specs and the
"implementation" of a subsystem.  I would be reluctant to see this
principle violated.

In fact, "private" children should more properly be
called "body" children.

>
> For instance, originally in Claw we put the low-level Win32 interface in a
> series of private packages. However, these packages cannot be accessed in
> the private part of the public types. That means that either we had to avoid
> strong typing in the low-level interface, or abandon the private package
> structure.

An alternative structure is to make these *public* packages
but with essentially all of their declarations in the private part.
Is there a reason why this wouldn't work?

>
> For instance, a possible image list package would look like:
>
>     package Claw.Low_Level_Image_Lists is
>         type HImage_List is new DWord;
>         type IL_Flags is new UInt;
>         ILR_DEFAULTCOLOR : constant IL_Flags := 16#0000#;
>         ILR_MONOCHROME   : constant IL_Flags := 16#0001#;
>          ...
>         type Image_Kind_Type is (Bitmap, Icon, Cursor);
>         for Image_Kind_Type use (Bitmap => 0, Icon => 1, Cursor => 2);
>
>         function Image_List_Load_Image (Name     : in Claw.Win32.LPCStr;
>                                         Width    : in Claw.Int;
>                                         Image_Kind : in Image_Kind_Type;
>                                         Flags    : in IL_Flags) return
> HImage_List;
>         pragma Import (StdCall, Image_List_Load_Image,
> "ImageList_LoadImageA");
>
>           ...
>     end Claw.Low_Level_Image_Lists;
>
>     with Claw.Low_Level_Image_Lists; -- Illegal!
>     package Claw.Image_List is
>        type Image_List_Type is tagged private;
>        procedure Load_Image (Image_List : in out Image_List_Type; Image : in
> String;
>                               Monochrome : in Boolean := False);
>          ...
>     private
>        type Image_List_Type is tagged record
>         Handle : Claw.Low_Level_Image_Lists.HImage_List;
>             Flags : Claw.Low_Level_Image_Lists.IL_Flags;
>               ...
>        end record;
>     end Claw.Image_List;
>
> We ended up moving things to the private part of the parent (Claw) [which
> makes it very large], eliminating some of the strong typing (since users
> don't access this code, it only makes our job harder), and not bothering
> with the private packages in the first place (putting the entire contents
> into the private part of the Image_List package; but of course that mixes up
> the high-level and low-level code).

I would think public children with essentially all of their interesting
decls in their private part would help break these big private parts
up.

>
> ----
>
> I haven't yet looked at the visibility ramifications of such a feature, but
> I will do so if there is sufficient interest in working out a full proposal.

****************************************************************

From: Pascal Leroy
Sent: Thursday, February 15, 2001 9:50 AM

> An alternative structure is to make these *public* packages
> but with essentially all of their declarations in the private part.
> Is there a reason why this wouldn't work?

I don't understand this.  Declarations in the private part are not visible
anyway, so what good would it do?  Could you give an example of what you
have in mind?

****************************************************************

From: Randy Brukardt [Randy@RRSoftware.Com]
Sent: Thursday, February 15, 2001 11:49 AM

> An alternative structure is to make these *public* packages
> but with essentially all of their declarations in the private part.
> Is there a reason why this wouldn't work?

Sure, no one would have visibility on the declarations in the private part.
How could you use them?

You must have had something else in mind; could you recast my example as you
suggest?

****************************************************************

From: Tucker Taft
Sent: Thursday, February 15, 2001 12:11 PM

Pascal Leroy wrote:
>
> > An alternative structure is to make these *public* packages
> > but with essentially all of their declarations in the private part.
> > Is there a reason why this wouldn't work?
>
> I don't understand this.  Declarations in the private part are not visible
> anyway, so what good would it do?  Could you give an example of what you
> have in mind?

Good point.  I realize I was misremembering a suggestion
by Robert Eachus.  The "trick" is to have an immediate parent
which has all of its declarations in its private part, and then
use renaming to rename the child so that it is directly beneath
its grandparent.  For example:

    package Claw is
       ...
    end Claw;

    package Claw.Hidden is
      private
         -- lots of private junk
    end Claw.Hidden;

    package Claw.Hidden.Child is
      -- useful stuff
    private
      -- Claw.Hidden private part is visible here
    end Claw.Hidden.Child;

    with Claw.Hidden.Child;
    package Claw.Child renames Claw.Hidden.Child;

Not particularly elegant, but might solve the problem.

****************************************************************

From: Randy Brukardt
Sent: Thursday, February 15, 2001 1:49 PM

Well, Claw has 6 private low-level packages (otherwise, *they* get too
large -- Win32 is huge). Would you like to try this solution for a set of
interrelated private packages?? :-) :-)

This is, after all, essentially what we did to work around this problem: we
declared lots of stuff in the private part of the ultimate parent (Claw),
but the effect is to bloat that package. It doesn't provide a solution, just
a work-around.

****************************************************************

From: Randy Brukardt
Sent: Thursday, February 15, 2001 6:19 PM

We've gotten so fixed on Tucker's silly workaround suggestion that no one
has addressed his real concerns...

> This is not a trivial change.  Currently, private children are *never*
> needed at compile-time of public specs (ignoring macro expansion
> requirements related to generics and inlines, of course!).  This
> allows a strong physical separation between the public specs and the
> "implementation" of a subsystem.  I would be reluctant to see this
> principle violated.
>
> In fact, "private" children should more properly be
> called "body" children.

You are forgetting that the private part of a spec really is part of the
*implementation* of a unit, not part of the specification. So, the current
situation is that part of the implementation can use private units, and part
don't.

If you really want to have this sort of physical separation, we have to have
some way to put private parts in a separate file. That seems like a much
more radical change than "with private" would be.

Given that Robert indicated that ACT was thinking about implementing
something on that line, perhaps it would be worthwhile to engage in a bit of
on-the-fly language design.

Here are my assumptions:

  1) We don't want to change the invariant that the size of an Ada entity is
known once the spec is compiled. Eliminating that would be a massive change
to Ada compilers, and I really doubt that any such idea could get much
support from implementors.
  2) We do want to allow a separate private part have its own context
clause, and allow private units to be withed there.
  3) We need rules that would work both in source-based and "traditional"
compiler structures.
  4) We don't need any additional functionality in the private part other
than (2).

(1) implies that the separate private part must be available when the
specification is compiled. For the "traditional" model, that means either it
must be compiled first (but what could that mean? It could depend on parts
of the spec) or compiled at the same time as the spec. For the
"source-based" model, this means that the source must be available when the
spec is compiled/used.

Assuming that the private part is available when the spec is compiled, the
separate private part would essentially be an "include" file, and shouldn't
cost much additional work in compilers. Most of the work would go into the
functionality of "with private".

Syntax for this seems hard to come up with. The best I can come up with
would be:

    <context_clause>
    package <Name> is
        <public declarations>
    private is separate;
    end <Name>;

    <context clause>
    separate (<Name>)
    package <Name> private is
        <private declarations>
    end <Name>;

Clearly, we would need a rule requiring the separate private to be available
when the spec is compiled -- and that is very different than other
separates, which are "real" separate compilation. We also would need to
extend the permissions in 10.1.4(7) to allow removing the spec from the
library when the private part is "added to the environment".

I guess my primary objection to this idea is that it isn't what it looks
like -- the private part is not really independent of the specification. But
that isn't necessarily a big deal (and different syntax might help here).

Tuck, would a proposal on this line address your objection??

****************************************************************

From: Robert A Duff
Sent: Thursday, February 15, 2001 8:14 PM

Randy suggests:

> Syntax for this seems hard to come up with. The best I can come up with
> would be:
>
>     <context_clause>
>     package <Name> is
>         <public declarations>
>     private is separate;
>     end <Name>;
>
>     <context clause>
>     separate (<Name>)
>     package <Name> private is
>         <private declarations>
>     end <Name>;

If I were designing the language from scratch, I would put the "imports"
(with_clauses) *inside* the thing importing.  And the private part would
be a separate syntactic entity, presumably in a separate file.  Or it
wouldn't exist at all.

But we're stuck with private parts.  Sigh.

I suggest this syntax:

    <context_clause>
    package <Name> is
        <public declarations>
    end <Name>;

    <context clause>
    package <Name> private is
        <private declarations>
    end <Name>;

Presumably, most compilers would require that the private part "exist"
when compiling clients, and when compiling the visible part itself.
No need to make it look like a subunit, IMHO.

****************************************************************

From: Randy Brukardt
Sent: Thursday, February 15, 2001 8:33 PM

> I suggest this syntax:
>
>     <context_clause>
>     package <Name> is
>         <public declarations>
>     end <Name>;
>
>     <context clause>
>     package <Name> private is
>         <private declarations>
>     end <Name>;
>
> Presumably, most compilers would require that the private part "exist"
> when compiling clients, and when compiling the visible part itself.
> No need to make it look like a subunit, IMHO.

The problem with that is that a compiler couldn't tell the difference
between a package spec that has a separate private part, and one that has no
private part at all. We fixed problems like that in Ada 95, I don't think
we'd want to reintroduce them. So there has to be some sort of stub in the
package spec.

****************************************************************

From: Pascal Leroy
Sent: Friday, February 16, 2001 2:44 AM

> > This is not a trivial change.  Currently, private children are *never*
> > needed at compile-time of public specs (ignoring macro expansion
> > requirements related to generics and inlines, of course!).  This
> > allows a strong physical separation between the public specs and the
> > "implementation" of a subsystem.  I would be reluctant to see this
> > principle violated.

I don't see why Tuck considers this principle so important.  This is really
throwing the baby out with the bathwater.  I have run into the problem
decribed by Randy several times myself (among other things, in implementing
some of the language-defined units, eg strings and I/O) and my conclusion
was that private units are like limited private types, they look nice but
are unusable in practice.

> > In fact, "private" children should more properly be
> > called "body" children.
>
> You are forgetting that the private part of a spec really is part of the
> *implementation* of a unit, not part of the specification. So, the current
> situation is that part of the implementation can use private units, and
> part don't.

Absolutely.  This is why Tuck's principle is flawed in my opinion.

> If you really want to have this sort of physical separation, we have to have
> some way to put private parts in a separate file. That seems like a much
> more radical change than "with private" would be.

I don't like the direction that this discussion is taking.  "with private"
is really quite simple, and I suspect we could come up with a proposal
and/or experimental implementations quickly, if we could overcome Tuck's
reluctance.  On the other hand, separate private parts are a much bigger
change, especially for library-based compilers (I don't understand what it
means for the separate private part to be "available" when compiling the
spec; this doesn't make any sense for library-based compilers; if it did, we
would not have trouble with mutually-dependent packages).

> Given that Robert indicated that ACT was thinking about implementing
> something on that line...

And that's fine.  First because GNAT can do what it wants in a non-standard
mode (I'm told that it can even compile C code in a non-standard mode :-)
and second because it's useful to do experiments on possible extensions to
the language.

But if we want a solution quickly (and that seems important because it is a
real problem that real people are having right now) then it will have to be
some form of "with private".

****************************************************************

From: Ehud Lamm
Sent: Friday, February 16, 2001 8:38 AM
>
> I don't like the direction that this discussion is taking.  "with private"
> is really quite simple, and I suspect we could come up with a proposal
> and/or experimental implementations quickly, if we could overcome Tuck's
> reluctance.


I agree. It sems pretty much straightforward, and has some important
benefits for readability and maintenance. As this relates to layered
achitectural style, which I find to be the corner stone of abstraction, I
find this esp. important.
It also makes the progammers decision explicit: Does he want the unit to be
visibile in the public part of the spec? Making such decisions explicit was
mentioned in the  steelman, and for good reasons.

****************************************************************

From: Robert A Duff
Sent: Friday, February 16, 2001 10:37 AM

Randy says:

> The problem with that is that a compiler couldn't tell the difference
> between a package spec that has a separate private part, and one that has no
> private part at all. We fixed problems like that in Ada 95, I don't think
> we'd want to reintroduce them.

We fixed one "problem" like that: optional package bodies.  However, I
think that was a mistake.  I think there *was* no language problem.
The problem was an implementation one: Ada 83 compilers ought to have
checked whether an optional body exists.  They didn't, and that led to
the error-prone behavior.

Note that GNAT originally had the *same* error-prone behavior.  If an
optional body existed on disk, GNAT would silently ignore it.  GNAT
would only give the error message if you explicitly asked it to compile
the file, thus defeating the whole point of the new language rule
disallowing optional bodies.  My point here is not to gripe about GNAT
(after all, they have long-since fixed that bug); my point is that this
is an issue of how you define what's in the program library (that is, an
implementation issue), and not a language issue.

>... So there has to be some sort of stub in the
> package spec.

I don't agree.

Pascal says:

> I don't like the direction that this discussion is taking.  "with private"
> is really quite simple, and I suspect we could come up with a proposal
> and/or experimental implementations quickly, if we could overcome Tuck's
> reluctance.  On the other hand, separate private parts are a much bigger
> change, ...

True.  But "with private" seems aesthetically unappealing to me.

>...especially for library-based compilers (I don't understand what it
> means for the separate private part to be "available" when compiling the
> spec; this doesn't make any sense for library-based compilers; if it did, we
> would not have trouble with mutually-dependent packages).

I don't see what the big deal is.  Your compiler has some file-naming
conventions (foo.1.ada, etc), so it seems like you could train it to
look for private parts according to some convention.  Or require the
user to tell you where it is.

But if you and Randy both say so, I suppose I must be wrong.

> > Given that Robert indicated that ACT was thinking about implementing
> > something on that line...
>
> And that's fine.  First because GNAT can do what it wants in a non-standard
> mode (I'm told that it can even compile C code in a non-standard mode :-)
> and second because it's useful to do experiments on possible extensions to
> the language.

Well, the feature won't be useful to *me* unless it's implemented by
more than just GNAT.

> But if we want a solution quickly (and that seems important because it is a
> real problem that real people are having right now) then it will have to be
> some form of "with private".

Perhaps you're right, but "with private" will look pretty silly if and
when we have private parts in separate files, or Tuck's suggestions
about putting things in the body.

****************************************************************

From: Randy Brukardt
Sent: Friday, February 16, 2001 10:37 PM

Bob says, replying to me:

> Randy says:
>
> > The problem with that is that a compiler couldn't tell the difference
> > between a package spec that has a separate private part, and one that has no
> > private part at all. We fixed problems like that in Ada 95, I don't think
> > we'd want to reintroduce them.
>
> We fixed one "problem" like that: optional package bodies.  However, I
> think that was a mistake.  I think there *was* no language problem.
> The problem was an implementation one: Ada 83 compilers ought to have
> checked whether an optional body exists.  They didn't, and that led to
> the error-prone behavior.

In a library-based compiler, that is impossible. If the code hasn't been
submitted to the compiler, it doesn't know about it. In a source-based
compiler, that *might* be possible.

But in any case, that wasn't the problem. The problem with Ada 83 was that
if the body became obsolete, it silently disappeared from the program. Some
compilers gave warnings about this; but doing anything else was incorrect.
There even was an ACVC test to force this (non-friendly) behavior: Janus/Ada
gave a link error until we had to "fix" it to ignore the error in that one
special case just so we could validate.

In our case, at least we gave a warning, because we had to write a bunch of
extra code to make that ACVC test pass. The whole point of the change in Ada
95 was to get rid of that ACVC test.

> >... So there has to be some sort of stub in the
> > package spec.
>
> I don't agree.

I still don't agree with you.

Then Bob replies to Pascal:

> Pascal says:
>
> > I don't like the direction that this discussion is taking.  "with private"
> > is really quite simple, and I suspect we could come up with a proposal
> > and/or experimental implementations quickly, if we could overcome Tuck's
> > reluctance.  On the other hand, separate private parts are a much bigger
> > change, ...
>
> True.  But "with private" seems aesthetically unappealing to me.

Can't argue with that. Which is why I suggested a brief foray into other
possible solutions.

> >...especially for library-based compilers (I don't understand what it
> > means for the separate private part to be "available" when compiling the
> > spec; this doesn't make any sense for library-based compilers; if it did, we
> > would not have trouble with mutually-dependent packages).
>
> I don't see what the big deal is.  Your compiler has some file-naming
> conventions (foo.1.ada, etc), so it seems like you could train it to
> look for private parts according to some convention.  Or require the
> user to tell you where it is.
>
> But if you and Randy both say so, I suppose I must be wrong.

You're wrong. :-)

For Janus/Ada, the compiler has no naming conventions. (The Make tool does,
but that's a different issue). The only units that the compiler (and program
library) knows about are those that it has been given to compile. There may
be other source laying around, but it is irrelevant.

To implement some sort of separate private part, we'd have to "pre-compile"
it (probably just do a syntax check) to insert it into the library; then it
would really be compiled when the stub was seen. Janus/Ada is syntax-based:
the only time it does something is when the syntax demands it. Thus, reading
the library happens only when there is a stub.

I think you're also putting a terrible burden on the reader of the source if
there is no indication that there is a private part missing. How would they
know if an "optional" private part (just like an optional body, not required
because there is nothing deferred) even exists? We don't want to design
features that make Ada HARDER to maintain.

Anyway, this would put a terrible new burden on the tools (especially the
make tool), and I suspect it will be a non-starter for that reason alone.

****************************************************************

From: Tucker Taft
Sent: Friday, February 16, 2001 8:46 AM

Randy Brukardt wrote:
>
> We've gotten so fixed on Tucker's silly workaround suggestion ...

Hey, I resent that ;-).

> ... that no one has addressed his real concerns...
>
> > This is not a trivial change.  Currently, private children are *never*
> > needed at compile-time of public specs (ignoring macro expansion
> > requirements related to generics and inlines, of course!).  This
> > allows a strong physical separation between the public specs and the
> > "implementation" of a subsystem.  I would be reluctant to see this
> > principle violated.
> >
> > In fact, "private" children should more properly be
> > called "body" children.
>
> You are forgetting that the private part of a spec really is part of the
> *implementation* of a unit, not part of the specification. So, the current
> situation is that part of the implementation can use private units, and part
> don't.

I don't see it that way.  When I present Ada to neophytes, I say
the visible part is the "logical interface" and the
private part of the spec is the "physical interface" and
the body is the "implemenation."

I think rather than trying to make private parts more sophisticated,
we should investigate simplifying them, and pushing more stuff
to the body.  It is clear that in some cases, the size of a type
is not known at compile-time, e.g. when the type includes a nested
array component whose length is not known at compile time.  This
implies that compilers have no problem dealing with such types,
and would seem a small step to introduce a kind of private
type where the full type information is deferred to the body.
(For compilers like RR where nested dynamic components are handled
with a level of indirection, clearly such a private type would also
involve a level of indirection.)

The other thing which really wants to be deferred to a body
is the full declaration for a deferred constant, so that large constant
tables can be given in a body rather than in a spec.

So...

How about something like:

   type Priv(Discrim : Integer) is private;
   Null_Priv : constant Priv;

 private

   type Priv(Discrim : Integer) is record in body;
   Null_Priv : constant Priv in body;


Clearly declaring an object of type Priv or using Null_Priv implies
an elaboration check that the corresponding full declaration in the
body has been elaborated.  Something like this additional elaboration
check will be needed in any case if we postpone elaboration of
the entire private part.

Of course only composite types could have their full declaration
postponed into the body.  Otherwise pass by copy could be
truly nasty.

> ...
> Tuck, would a proposal on this line address your objection??

Not really.  I prefer something more along the lines above, where
individual declarations can have their full definitions deferred
into the body.

****************************************************************

From: Robert A Duff [bobduff@world.std.com]
Sent: Friday, February 16, 2001 4:46 PM

> I don't see it that way.  When I present Ada to neophytes, I say
> the visible part is the "logical interface" and the
> private part of the spec is the "physical interface" and
> the body is the "implemenation."

I think that view of private parts is rather unusual.  I find it strange
to call the private part an "interface".

Do you consider a procedure body to be a "physical interface" in the
case where it is inlined?  It's just like a private part, in the sense
that the compiler looks at it in order to generate (presumably better)
code.

The explanation I've heard many times (and agree with) is that the
private part contains stuff that logically belongs in the body, but for
efficiency, we want the compiler to be able to see it (when compiling
clients).  In other words, it's an efficiency hack.  Calling it an
"interface" of some sort seems to raise it to a higher level.

(In case you can't tell: If I were designing a language from scratch, it
would not have private parts.  It would have package specs defining the
interface (and only the interface), and package bodies defining the
implementation.  And in fact, I'm *always* designing a language, in my
head.  It's my hobby. ;-))

> I think rather than trying to make private parts more sophisticated,
> we should investigate simplifying them, and pushing more stuff
> to the body.

This sounds like an excellent plan.  Should have happened 20 years ago.
;-)

However, such a feature would be incomplete without a new pragma
analogous to Inline.  This new pragma would tell the compiler to look at
the body of a with-ed package, and generate code that depends on the
full type and full constant declarations it finds there (eg, know the
size of a record at compile time, if possible).  This is what pragma
Inline does for procedures: look at the package body, and depend on the
contents of the procedure body it finds there.

The effect on dependences and compilation order and whatnot for this new
pragma would be as for pragma Inline (and these effects depend on the
library model of that compiler).

If you use this pragma, you should get code (in client packages)
identical to what you get now, when you put the full type in the private
part, so the compiler can look at it.

This new pragma seems important to me:  If you don't have it, you're
stuck with an annoying choice between efficiency at run time, versus
the benefits of putting the thing in the body: efficiency of compile
time, ability to "with" private children, better management of
source-file variants.  Furthermore, if you put something in the body,
and you later decide that's too inefficient, you don't want to move it
to the private part, because that wrecks the structure of your program
-- you might have to rearrange all your packages, make private packages
public, etc.  Much better to slap a pragma on it.  Just like it's much
better to use pragma Inline than to hand-inline the code of that
procedure.

> It is clear that in some cases, the size of a type
> is not known at compile-time, e.g. when the type includes a nested
> array component whose length is not known at compile time.  This
> implies that compilers have no problem dealing with such types,
> and would seem a small step to introduce a kind of private
> type where the full type information is deferred to the body.
> (For compilers like RR where nested dynamic components are handled
> with a level of indirection, clearly such a private type would also
> involve a level of indirection.)
>
> The other thing which really wants to be deferred to a body
> is the full declaration for a deferred constant, so that large constant
> tables can be given in a body rather than in a spec.
>
> So...
>
> How about something like:
>
>    type Priv(Discrim : Integer) is private;
>    Null_Priv : constant Priv;
>
>  private
>
>    type Priv(Discrim : Integer) is record in body;

Why "record"?  Does the compiler need to know it's a record?
Is it allowed to be an array, task, protected?

>    Null_Priv : constant Priv in body;
>
> Clearly declaring an object of type Priv or using Null_Priv implies
> an elaboration check that the corresponding full declaration in the
> body has been elaborated.  Something like this additional elaboration
> check will be needed in any case if we postpone elaboration of
> the entire private part.

No, no, no!  The proposal to split out the private part into a separate
syntactic entity, presumably in a separate source file, should *not*
change the run-time semantics in the slightest.  The private part should
still be elaborated immediately after the visible part.

> Of course only composite types could have their full declaration
> postponed into the body.  Otherwise pass by copy could be
> truly nasty.

Sigh.

> > ...
> > Tuck, would a proposal on this line address your objection??
>
> Not really.  I prefer something more along the lines above, where
> individual declarations can have their full definitions deferred
> into the body.

I also prefer something along the lines of the above, but I still don't
understand Tuck's desire to preserve some sort of "physical interface".
If we have to have private parts, I don't see why they can't see private
children.  But I agree with Tuck that moving information from private
parts to bodies is the right idea.

****************************************************************

From: Michael Yoder
Sent: Friday, February 16, 2001 7:01 PM

On this issue I agree with Pascal and Ehud. But let me start by quoting Bob
quoting Tucker:

> > I think rather than trying to make private parts more sophisticated,
> > we should investigate simplifying them, and pushing more stuff
> > to the body.
>
>This sounds like an excellent plan.  Should have happened 20 years ago.
>;-)
[discussion of how Bob's ideal language would work snipped]

I'm skeptical we had the knowledge needed to do this right 20 years
ago.  I'm skeptical we know *today* how to do it right.  (Yes, it is
possible if code generation is always done at what we call "link
time.")  But be that as it may, "with private" is preferable unless we can
finish all of Tucker's investigations in the reasonably near future.  "With
private" cuts the Gordian knot and Tucker is advocating teasing it
apart.  It would be better to do "with private" and then move towards a
Duffian or Taftian ideal language; if we arrive, "with private" and private
parts can then be made deprecated features.

I've often wanted to insert a second context clause right after the keyword
'private' in a package specification; each time my workaround was to
promote stuff I wanted in private packages into a public "wannabe private"
package.

> > > ...
> > > Tuck, would a proposal on this line address your objection??
> >
> > Not really.  I prefer something more along the lines above, where
> > individual declarations can have their full definitions deferred
> > into the body.
>
>I also prefer something along the lines of the above, but I still don't
>understand Tuck's desire to preserve some sort of "physical interface".
>If we have to have private parts, I don't see why they can't see private
>children.  But I agree with Tuck that moving information from private
>parts to bodies is the right idea.

I also prefer this, but I'd like to have "with private" in the interim
until I get all of it.

****************************************************************

From: Randy Brukardt
Sent: Friday, February 16, 2001 10:47 PM

Tucker said:

(Discussion of unusual world-view deleted :-)

> I think rather than trying to make private parts more sophisticated,
> we should investigate simplifying them, and pushing more stuff
> to the body. ...

> How about something like:
>
>   type Priv(Discrim : Integer) is private;
>   Null_Priv : constant Priv;
>
> private
>
>   type Priv(Discrim : Integer) is record in body;
>   Null_Priv : constant Priv in body;
>
>Clearly declaring an object of type Priv or using Null_Priv implies
>an elaboration check that the corresponding full declaration in the
>body has been elaborated.  Something like this additional elaboration
>check will be needed in any case if we postpone elaboration of
>the entire private part.

I wouldn't be adverse to working on this idea further. It seems to just be
syntactic sugar for:

   type Priv(Discrim : Integer) is private;
   Null_Priv : constant Priv;

 private

   type <Anon_Priv> (Discrim : Integer); -- Deferred to body.
   type Priv(Discrim : Integer) is access <Anon_Priv> (Discrim);
   Null_Priv : constant Priv in body := <Anon_Null_Priv_Func>;

The only new thing about this would be the handling of the discriminants.

However, I think that the real-time and safety-critical people wouldn't be
happy: the last thing they want is more dynamic allocation of memory. They'd
probably never use this feature, and thus we'd still need "with private".

(I think Bob's pragma Inline for these is unworkable, since it couldn't be
implemented with link-time inlining; and thus would require library
dependencies that I simply will not stand for.)

****************************************************************

From: Robert A Duff
Sent: Saturday, February 17, 2001 9:43 AM

> I wouldn't be adverse to working on this idea further. It seems to just be
> syntactic sugar for:
>
>    type Priv(Discrim : Integer) is private;
>    Null_Priv : constant Priv;
>
>  private
>
>    type <Anon_Priv> (Discrim : Integer); -- Deferred to body.
>    type Priv(Discrim : Integer) is access <Anon_Priv> (Discrim);
>    Null_Priv : constant Priv in body := <Anon_Null_Priv_Func>;
>
> The only new thing about this would be the handling of the discriminants.

No, I don't think it's quite that simple.  For Tucker's idea, you want
the compiler to manage the storage.  For the incomplete type deferred to
the body (which was a younger Tucker's idea, by the way!), you have an
explicit access type, so the programmer is required to manage the
storage (which is why I never use that feature unless I wanted a pointer
type anyway).

> However, I think that the real-time and safety-critical people wouldn't be
> happy: the last thing they want is more dynamic allocation of memory. They'd
> probably never use this feature, and thus we'd still need "with private".

It's no more dynamic than an array of run-time-known size.  That is,
it's not necessary to use the heap.  (If some compilers choose to use
the heap, that's fine, but we should preserve the feasibility of never
using the heap except for explicit access types).

> (I think Bob's pragma Inline for these is unworkable, since it couldn't be
> implemented with link-time inlining; and thus would require library
> dependencies that I simply will not stand for.)

If some compilers can't implement the new pragma Inline, that's OK.
But I think it's extremely important to standardize the pragma,
so those compilers that care about this issue can support it
(portably!).  Most compilers would in fact have no trouble implementing it.

****************************************************************

From: Randy Brukardt
Sent: Monday, February 19, 2001 4:16 PM

> No, I don't think it's quite that simple.  For Tucker's idea, you want
> the compiler to manage the storage.  For the incomplete type deferred to
> the body (which was a younger Tucker's idea, by the way!), you have an
> explicit access type, so the programmer is required to manage the
> storage (which is why I never use that feature unless I wanted a pointer
> type anyway).

I meant that to be implied. I should have added a Storage_Pool clause to
indicate that. I was mainly concerned about the code generation, which is the
same as above with an appropriate initialization New at each declaration.

Alternatively, I could have wrapped the access in a controlled type to do that.
Still, there is nothing new here...

> It's no more dynamic than an array of run-time-known size.  That is,
> it's not necessary to use the heap.  (If some compilers choose to use
> the heap, that's fine, but we should preserve the feasibility of never
> using the heap except for explicit access types).

I wasn't talking about the heap per-se. I don't think that the Safety-critical
people use dynamic arrays, either. That's because they don't want
non-deterministic memory usage. I stand by my comment.

****************************************************************

From: Pascal Leroy
Sent: Saturday, February 17, 2001 5:01 AM

Bob (who is always designing languages) explained:

> I think that view of private parts is rather unusual.  I find it strange
> to call the private part an "interface".
>
> The explanation I've heard many times (and agree with) is that the
> private part contains stuff that logically belongs in the body, but for
> efficiency, we want the compiler to be able to see it (when compiling
> clients).  In other words, it's an efficiency hack.  Calling it an
> "interface" of some sort seems to raise it to a higher level.

I completely agree with this view.  The notion that something which is
invisible to clients is an "interface" doesn't make sense to me.

Tuck proposed:

> > I think rather than trying to make private parts more sophisticated,
> > we should investigate simplifying them, and pushing more stuff
> > to the body.

I can agree with this, although as Bob pointed out we would want a pragma of
some sort (heck, it could be Inline applied to a type) to force the compiler
to generate decent code.

However, I believe we need to be pragmatic here.  Pushing more stuff to the
body is probably sensible, but it is going to take several years to
refine/understand the consequences of this new model.  On the other hand,
let me say it once more, "with private" could work tomorrow (tomorrow in ARG
terms probably means next year, I'm sure we all realize that). Also, we have
to keep in mind that there is a lot of code out there that uses private
parts, and restructuring that code to use the "in body" clause might be a
lot of work.  On the other hand, adding "private" to a couple of with
clauses is an extremely cheap change.

So I guess I am saying that I like Mike Y's proposal:

> It would be better to do "with private" and then move towards a
> Duffian or Taftian ideal language; if we arrive, "with private" and private
> parts can then be made deprecated features.

****************************************************************

From: Robert A Duff
Sent: Saturday, February 17, 2001 9:37 AM

> I can agree with this, although as Bob pointed out we would want a pragma of
> some sort (heck, it could be Inline applied to a type) to force the compiler
> to generate decent code.

I almost suggested extending pragma Inline.

Of course it doesn't "force" anything -- it's your customers with open
checkbooks that do the forcing.  ;-)

> So I guess I am saying that I like Mike Y's proposal:
>
> > It would be better to do "with private" and then move towards a
> > Duffian or Taftian ideal language; if we arrive, "with private" and private
> > parts can then be made deprecated features.

Sounds reasonable to me.

****************************************************************

From: Tucker Taft
Sent: Saturday, February 17, 2001 1:53 PM

> I almost suggested extending pragma Inline.

I think this somewhat defeats the purpose of the "in body."
I see the "in body" as allowing more dynamically constructed
systems.  Pragma inline goes just the opposite, increasing
the amount of statically bound decisions.  I also don't
see why this is expected to be so inefficient, given how often
one ends up with a dynamically-sized type already.

Perhaps the idea is that while the system is being developed, the
dynamic approach is great, but once you want to deliver the most
heavily optimized version, you can "inline" things.  I can't imagine
going to the bother of using "in body" if you "inline" right away.

****************************************************************

From: Robert A Duff
Sent: Saturday, February 17, 2001 9:53 AM

Randy says:

> In our case, at least we gave a warning...

Well, if you can give a warning, I don't see why you can't just as
easily give an error.

The implementation I'm imagining for a library-based compiler is that
the compiler has a rule that if there's a private part, you have to
submit it to the compiler at the same time as you submit the visible
part.  Eg, if there's a command-line interface, you would type in two
file names.  If you don't, and the private part turns out to exist at
link time, then complain.

But I'm not dead-set against having a stub-like syntax.

> I think you're also putting a terrible burden on the reader of the source if
> there is no indication that there is a private part missing.

I find that argument somewhat convincing.  But not entirely.

When I want to know if a package body exists, I go and look at its file.
If that file doesn't exist, then the package body doesn't exist.
(I'm presumable either using some file-naming conventions voluntarily,
or else my compiler forces me to.)  I certainly don't carefully read the
spec, to see if a body is required.

You also can't tell from a package spec whether any children exist.

So the private part doesn't seem like that big of a deal.
To tell whether it exists, go look for it in the directory where you
keep your source code.

****************************************************************

From: Pascal Leroy
Sent: Sunday, February 18, 2001 4:26 AM

So the model you have in mind is merely a #include, right?  Fine, but that's
outside of the language in my opinion.  I don't believe you can phrase the
above discussion in RM terms, i.e. "entered in the environment."

****************************************************************

From: dewar@gnat.com
Sent: Sunday, February 18, 2001 7:56 AM

<<We fixed one "problem" like that: optional package bodies.  However, I
think that was a mistake.  I think there *was* no language problem.
The problem was an implementation one: Ada 83 compilers ought to have
checked whether an optional body exists.  They didn't, and that led to
the error-prone behavior.>>

I strongly disagree, suppose you had the following:

a spec p
a body p
where the body was not required

Now you build a program with the spec and body, and everything works
fine.

Now you edit the spec, and you recompile the spec, the body simply gets
left out.

What do you mean "check whether an optional body exists", you cannot
check if an optional body exists in the normal case, without searching
the universe. Yes, you can warn if one happens to be around, and you
can warn that one used to exist.

But you MUST be allowed (in Ada 83) to rebuild the executable with
only the new spec, and not the new body. The compiler cannot prevent
you from constructing this modified program, since it is legal.

The point in Ada 95 was to remove the requirement of being able to
construct the "wrong" program. Since every Ada 83 compiler had to
support this capability, and the capability itself is what was
fundamentally flawed, I think the change to Ada 95 was highly desirable.

<<Note that GNAT originally had the *same* error-prone behavior.  If an
optional body existed on disk, GNAT would silently ignore it.  GNAT
would only give the error message if you explicitly asked it to compile
the file, thus defeating the whole point of the new language rule
disallowing optional bodies.  My point here is not to gripe about GNAT>>

That's completely confused, yes, that's a problem, one that might exist
in any compiler, but it has nothing whatsoever to do with the problem
we are talking about, and which this language solution exists.

The new Ada 95 feature is NOT talking about issues in building programs
in the first place, it is talking about the error prone behavior where
you modify a spec that does not require a body, and the modification
does not force a recompilation of the body. It is *ENTIRELY* that
modification scenario, required to "work" in all Ada 83 compilers
that the new Ada 95 feature is addressing.

What Bob Duff is referring wrt GNAT is that when you build a program
in the first place, where you have an improper body, then it is nice
if the automatic compilation tools make the effort to see if a body
is around (what on earth that means is of course very compilation
environment dependent). The "new" GNAT here searches everywhere on
the path for something that might be a body, and makes you get rid
of it. That's not always the right thing to do, but it is safer,
but this error check has nothing at all to do with the language
feature.

I am a bit surprised at this confusion, because this was a well
known problem in Ada 83, that was completely eliminated in Ada 95,
in all Ada 95 compilers, and in all versions of GNAT, and was a
welcome change in Ada 95.

Indeed if we have separated private parts, it is absolutely essential
in my view that we not repeat the mistake that Ada 83 made in this
area. Yes, you can defend against it to some limited extent by the
kind of peculiar searching around for possible peculiarities that
GNAT does, but that is not a desirable behavior.

Note incidentally that the RM appears to prohibit the GNAT behavior,
because there are specific rules about new units obsoleting old ones.
What we do for the ACVC runs is to use a crackpot (i.e. ACVC only)
script that sees GNAT issue the message of an unwelcome body or spec,
and then deletes it and transparently reattempts the compilation.

In other words, the following sequence must work as far as the
ACVC tests are concerned.

Introduce p.ads (spec needing body) and p.adb (body) into compilation
environment, and compile

Introduce new p.ads (spec not needing body) into compilation environment
and compile.

GNAT will reject the second attempt, but the ACVC test won't tolerate
that rejection, so we simply automatically delete the p.adb and proceed
(of course you would never want to do that automatically in real life,
which is why I call this a crackpot script).

****************************************************************

From: Tucker Taft
Sent: Saturday, February 17, 2001 1:47 PM

Pascal Leroy wrote:
> ...
> However, I believe we need to be pragmatic here.  Pushing more stuff to the
> body is probably sensible, but it is going to take several years to
> refine/understand the consequences of this new model.  On the other hand,
> let me say it once more, "with private" could work tomorrow (tomorrow in ARG
> terms probably means next year, I'm sure we all realize that).

I don't think this is a good argument.  I really don't want to
add something and then soon thereafter declare it obsolescent.

On the other hand, I do see some value in "with private" though
I hate the name, since it brings up bad memories of an Ada 9X
proposal of the same name.  Maybe "private with"?  We aren't
"with"ing the private part, but rather "privately" withing the visible
part, so I think "private with" might make more sense anyway,
although it may be a bit trickier to parse.

I also don't think we should ignore the possibility of moving the
"with" clauses to immediately after the word "private".

I personally think we should drop discussion of physically separating
the "private" part, and leave that to compilers to do if they
so choose, especially if it is supposed to be completely
semantically neutral.

But getting back to "private with" -- exactly what was the proposal?
I have lost it in all the other discussion.

Clearly we can't allow a parent package spec to "with" its own
private children.  So instead it must be siblings, nieces, etc.
that can "private with" their private siblings, aunts, etc.

I suppose an alternative is to simply allow these "with" clauses,
but then say that if the with'ed unit is private, it only becomes
visible in the private part.  This is roughly equivalent to saying
that when a unit is "with"ed, if it is a private child, it
is implicitly inserted at the end of the private part of its parent,
while if it is a public child, it is implicitly inserted at the
end of the visible part of its parent.  In any case, a spec
can never "with" its own descendant.

> ...
> So I guess I am saying that I like Mike Y's proposal:
>
> > It would be better to do "with private" and then move towards a
> > Duffian or Taftian ideal language; if we arrive, "with private" and private
> > parts can then be made deprecated features.

I really don't like this way of thinking.  We should be convinced
that "private with" is useful indefinitely, rather than putting
it in as a stop-gap.

I see "private with" as serving a different purpose than
the "in body" stuff.  It focuses on information hiding and
modularization, whereas the "in body" really opens up the
possibility for more dynamically constructed systems (similar to
the "with type" stuff).

****************************************************************

From: dewar@gnat.com
Sent: Sunday, February 18, 2001 9:13 AM

<<The explanation I've heard many times (and agree with) is that the
private part contains stuff that logically belongs in the body, but for
efficiency, we want the compiler to be able to see it (when compiling
clients).  In other words, it's an efficiency hack.  Calling it an
"interface" of some sort seems to raise it to a higher level.>>

This viewpoint seems exactly right in Ada 83, but surely is completely
wrong in Ada 95. The introduction of child packages that can see the
private part now means that indeed it is used as an interface for
the implementation, and I see Ada 95 code all the time where private
parts are full of subprogram specs that would never have fit the
Ada 83 model.

So I don't think you can turn back the clock at this stage, the nature
of private parts of packages has radically changed from the above
quoted viewpoint.

****************************************************************

From: Ehud Lamm
Sent: Monday, February 19, 2001 1:47 AM

Indeed. This is one prime reason to think that private parts as they are now
are problematic. They serve two very distinct semantic functions: to declare
implementation details that (per Ada-83) must be in the spec and to declare
the extension interface (similar to "protected" in C++).
I find the connection between child units and inheritance very elegant (see
Tucker Taft's LSN on this). However, outsiders (i.e., students) have a hard
time with this. Almost no one sees how to use the private part for extension
purposes unless told about this specifically.
I tried giving this as a riddle this semester ("Why does a pacakge have
procedures declared in the private part etc. etc.") and only one student
thought about child units.

However, I agree with Robert: We are too far into the game to change the
rules.

Notice that since the above means that the private part is indeed an
"interface" (that can be used only by children), it makes more sense to have
it _inside the spec_ and not in a  seperate file. It is not just a hack for
storing impl. details: it is part of the abstraction. This is esp. true when
the essence of the package is to allow extension (e.g, when it declares
abstract tagged types; or in the future when it declares interfaces).

****************************************************************

From: Tucker Taft [stt@avercom.net]
Sent: Saturday, February 17, 2001 3:36 PM

Pascal Leroy wrote:
> Bob (who is always designing languages) explained:
>
> > I think that view of private parts is rather unusual.  I find it strange
> > to call the private part an "interface".
> >
> > The explanation I've heard many times (and agree with) is that the
> > private part contains stuff that logically belongs in the body, but for
> > efficiency, we want the compiler to be able to see it (when compiling
> > clients).  In other words, it's an efficiency hack.  Calling it an
> > "interface" of some sort seems to raise it to a higher level.
>
> I completely agree with this view.  The notion that something which is
> invisible to clients is an "interface" doesn't make sense to me.

Well, I won't belabor the point, but it is clearly an "interface"
from the compiler's point of view, and even from the programmer's
point of view, 'size is visible, as are various other properties
revealed only in the private part such as by-reference, atomic,
volatile, etc.

I call it the "physical" interface in analogy with the layers in
a network protocol.  It is like the "physical link" level while
the visible part is more like the "application" level.  Conceivably
you could put the code for the body of a procedure in some other
computer, but to communicate with it, you would need to know at
least something about the physical representation of the data you
pass to it.

****************************************************************

From: Ted Baker
Sent: Sunday, February 18, 2001 11:57 AM

> I think that view of private parts is rather unusual.  I find it strange
> to call the private part an "interface".
>
> The explanation I've heard many times (and agree with) is that the
> private part contains stuff that logically belongs in the body, but for
> efficiency, we want the compiler to be able to see it (when compiling
> clients).  In other words, it's an efficiency hack.  Calling it an
> "interface" of some sort seems to raise it to a higher level.

The reason we want the compiler to be able to see it is that it
provides information that is NEEDED to implement the interface--
i.e., the lower-level details of the interface.

I realize that some people would like to move toward a more
dynamic, world, where no data representation details would need to
be bound by the interface.  However, there will always remain
situations (e.g., interfacing to hardware and to code in other languages,
and -- dare I ever hope? -- interfacing to code compiled with
a different Ada compiler) where data representation will necessarily
be a logical part of the interface to a software component.

****************************************************************

From: dewar@gnat.com
Sent: Sunday, February 18, 2001 12:26 AM

<<I personally think we should drop discussion of physically separating
the "private" part, and leave that to compilers to do if they
so choose, especially if it is supposed to be completely
semantically neutral.>>

No one is suggesting that this be part of the definition, just that it
would be nice if whatever solution is decided here made it easier for
compilers to do this ...

****************************************************************

From: Pascal Leroy
Sent: Sunday, February 18, 2001 4:22 AM

> On the other hand, I do see some value in "with private" though
> I hate the name, since it brings up bad memories of an Ada 9X
> proposal of the same name.  Maybe "private with"?

Ok, I changed the subject line of this message :-)

> We aren't
> "with"ing the private part, but rather "privately" withing the visible
> part, so I think "private with" might make more sense anyway,
> although it may be a bit trickier to parse.

I am not going to fight on the syntax, as long as the grammar remains
reasonably unambiguous.

> I also don't think we should ignore the possibility of moving the
> "with" clauses to immediately after the word "private".

I don't like that.  It's good for readability to have the with clauses at
the beginning of the unit, it summarizes the dependencies of the unit, eg in
terms of compilation ordering.  In fact, I believe that a number of "make"
tools out there work by scanning the beginning of the unit for withs and
separate.  Now they would have to go much farther.

Also, it seems that you would have some trouble distinguishing pragmas that
appear in declarative parts from pragmas that appear in context clauses.

> I personally think we should drop discussion of physically separating
> the "private" part, and leave that to compilers to do if they
> so choose, especially if it is supposed to be completely
> semantically neutral.

I couldn't agree more.

> I suppose an alternative is to simply allow these "with" clauses,
> but then say that if the with'ed unit is private, it only becomes
> visible in the private part.

No, that's not sufficient.  I believe you also want to "private with" public
units, but make it explicit that they are only needed for the private part.
That's useful for documentation and maintenance purposes.  And maybe these
units will later turn into private units, but you don't want to do the
required restructuring right now.  Again, think of all the code out there
that withs units for the sole purpose of writing a private part.

****************************************************************

From: Ehud Lamm
Sent: Sunday, February 18, 2001 8:57 AM

> > On the other hand, I do see some value in "with private" though
> > I hate the name, since it brings up bad memories of an Ada 9X
> > proposal of the same name.  Maybe "private with"?
>
> Ok, I changed the subject line of this message :-)

I wouldn't fight over this... To my (non native) ears the first wording
sounds better.

>
> > I also don't think we should ignore the possibility of moving the
> > "with" clauses to immediately after the word "private".
>
> I don't like that.  It's good for readability to have the with clauses at
> the beginning of the unit, it summarizes the dependencies of the unit, eg in
> terms of compilation ordering.  In fact, I believe that a number of "make"
> tools out there work by scanning the beginning of the unit for withs and
> separate.  Now they would have to go much farther.

I agree with Pascal. If/when the private part goes into a seperate file, the
with clauses might well follow, but as long as it remains in the spec, I
think the with clauses should stay where they are. Changing this can
introduce work and bugs to automatic tools, and is also bad for readability.
I think that it is again a situation of better being the enemy of good
enough. Unless the private part is eliminated, it is visible in the spec, so
why should we work hard to move the with clauses down a few lines?


> > I personally think we should drop discussion of physically separating
> > the "private" part, and leave that to compilers to do if they
> > so choose, especially if it is supposed to be completely
> > semantically neutral.

Quite. And this is why I agree that the with's should stay where they are,
for the time being.

****************************************************************

From: dewar@gnat.com
Sent: Monday, February 19, 2001 1:05 PM

<<I agree with Pascal. If/when the private part goes into a seperate file, the
with clauses might well follow, but as long as it remains in the spec, I
think the with clauses should stay where they are. Changing this can
introduce work and bugs to automatic tools, and is also bad for readability.
I think that it is again a situation of better being the enemy of good
enough. Unless the private part is eliminated, it is visible in the spec, so
why should we work hard to move the with clauses down a few lines?
>>

Note that the mere fact of the with's being at the top of the abstract
representation does not mean they have to be there in the physical
representation if you separate this into two separate files. There is
no rule that says that the only allowable way to split into two files
is to draw a line in the source :-)

****************************************************************

From: dewar@gnat.com
Sent: Sunday, February 18, 2001 8:49 AM

<<I agree. It sems pretty much straightforward, and has some important
benefits for readability and maintenance. As this relates to layered
achitectural style, which I find to be the corner stone of abstraction, I
find this esp. important.
It also makes the progammers decision explicit: Does he want the unit to be
visibile in the public part of the spec? Making such decisions explicit was
mentioned in the  steelman, and for good reasons.>>

Note that it is possible to implement this right now without any change
to the language (we investigated this possibility some time ago). All
you need is a pragma

with x; pragma Private_Only (x);

that says that the unit x can only be referenced in the private part.

Now you can allow the private part to be in a separate file, with the
WITH clauses in that file (and no junk pragma), and you just declare
that this is a representation of the text where the WITH goes where
it belongs with the pragma.

But it is nicer if something like this is at least semi-standardized :-)

****************************************************************

From: Randy Brukardt
Sent: Monday, February 19, 2001 4:47 PM

No, this doesn't solve the problem. The problem is that it is illegal to
with a private package in a public specification. No pragma can change that
(unless of course you're in "extensions" mode).

Thus we need a real extension to allow such withing; the rest of it is
nice-to-have, but seems to come along for free.

****************************************************************

From: dewar@gnat.com
Sent: Monday, February 19, 2001 5:00 PM

Sure, I understand this, but in my view this is the nice-to-have feature,
the really essential one is to conveniently enable separated private parts.

For example, we often find that the copyright on the private part is
completely different from the copyright on the public part, and it
would really be nice to have two documents (e.g. this happens with
the RM defined library).

****************************************************************

From: Randy Brukardt
Sent: Monday, February 19, 2001 5:26 PM

Humm. The problem outlined on C.L.A., and which I described, and which we're
trying to solve in AI-262 is the private package needed by the private part
problem.

Separated private parts only came up as a possible solution to this problem.
In my opinion, they are a nice-to-have, while the private package problem
contorts designs (and essentially makes private packages useless for their
intended purpose); thus it has a much higher priority in my view.

****************************************************************

From: Randy Brukardt [Randy@RRSoftware.Com]
Sent: Monday, February 19, 2001 4:39 PM

> But getting back to "private with" -- exactly what was the proposal?
> I have lost it in all the other discussion.

I never worked out the exact details; I asked whether it was worth doing so,
and the rest is history... (and a very large appendix in AI-262, and a new
record in messages on Ada-Comment since I took it over).

****************************************************************

From: Christoph Grein [christoph.grein@eurocopter.de]
Sent: Monday, February 19, 2001 2:30 AM
To: ada-comment@ada-auth.org
Subject: Re: [Ada-Comment] Possible amendment: with private

> But getting back to "private with" -- exactly what was the proposal?
> I have lost it in all the other discussion.

package S is  -- Note: not private, not in hierarchy T
  ...
end S;
-----------------------
package T is
  ...
end T;
-----------------------
private package T.Pr is
  ...
private
  ...
end T.Pr;
-----------------------
private with T.Pr, S;
pacakge T.C is
  -- T.Pr, S invisible here
private
  -- visible parts of T.Pr, S visible here
end T.C;
------------------------------------------------------------------
I'm not sure about the following:

private package X is  -- Note: no visible parent (except of course Standard).
  ...                 -- Does such a package currently,
private               -- i.e. without the proposed amendment,
  ...                 -- have any use?
end X;
-----------------------
private with X;  -- should this be allowed?
package Y is     -- Note: no hierarchical relation between X and Y
  -- X invisible here
private
  -- visible part of X visible here
end Y;

****************************************************************

From: Michael Yoder
Sent: Monday, February 19, 2001 4:20 PM

Tucker you wrote:

>Pascal Leroy wrote:
> > ...
> > However, I believe we need to be pragmatic here.  Pushing more stuff to the
> > body is probably sensible, but it is going to take several years to
> > refine/understand the consequences of this new model.  On the other hand,
> > let me say it once more, "with private" could work tomorrow (tomorrow
> in ARG
> > terms probably means next year, I'm sure we all realize that).
>
>I don't think this is a good argument.  I really don't want to
>add something and then soon thereafter declare it obsolescent.

I absolutely agree.  But I am nervous about this judgment unless we agree
on what "soon" means, and have strong confidence that we *can* declare it
obsolescent soon.


> > ...
> > So I guess I am saying that I like Mike Y's proposal:
> >
> > > It would be better to do "with private" and then move towards a
> > > Duffian or Taftian ideal language; if we arrive, "with private" and private
> > > parts can then be made deprecated features.
>
>I really don't like this way of thinking.  We should be convinced
>that "private with" is useful indefinitely, rather than putting
>it in as a stop-gap.
>
>I see "private with" as serving a different purpose than
>the "in body" stuff.  It focuses on information hiding and
>modularization, whereas the "in body" really opens up the
>possibility for more dynamically constructed systems (similar to
>the "with type" stuff).

Well, I may have misjudged by imagining that you and Bob were aiming at
nearly identical endpoints.  I think that in Bob's ideal endpoint it would
become obsolete.  I'm no longer sure about yours.  If not, it would never
become a deprecated feature unless Bob converted you.  :-)

****************************************************************

Questions? Ask the ACAA Technical Agent