Version 1.3 of ais/ai-30359.txt

Unformatted version of ais/ai-30359.txt version 1.3
Other versions for file ais/ai-30359.txt

!standard 12.03 (02)          04-11-19 AI95-00359-04/03
!standard 12.03.01 (01)
!standard 13.14 (05)
!class amendment 04-09-19
!status work item 04-09-19
!status received 04-09-19
!priority Medium
!difficulty Hard
!subject Partial generic instantations
!summary
To better support generic signature packages, and mutually dependent types that involve generic instantiations, syntax is defined to allow a generic instantiation to be split into two parts, a partial instantiation and a full (normal) instantiation.
For such a pair of instantiations, no freezing or elaboration occurs at the point of the partial instantiation, rather it is deferred until the full instantiation which completes it.
!problem
Ada 95 provides formal package parameters. One way of using these parameters is to define a "signature" for a class of abstractions, such as all set abstractions, or all physical unit abstractions, and then build a new generic abstraction on top of the original class of abstractions using this signature as the template for a formal package parameter.
Unfortunately, it is difficult to use signatures because of the fact that an instantiation freezes all of its actual parameters.
For example:
Given the signature for a set abstraction:
generic type Element is private; type Set is private; with function Size(Of_Set : Set) return Natural is <>; with function Union(Left, Right : Set) return Set is <>; with function Intersection(Left, Right : Set) return Set is <>; with function Empty return Set is <>; with function Unit_Set(With_Item : Element) return Set is <>; with function Nth_Element(Of_Set : Set) return Element is <>; package Set_Signature is end;
... we could define a generic that required some set abstraction, but it didn't care which one so long as it implemented the above signature:
generic with package Base_Set is new Set_Signature(<>); package Layered_Abstraction is type Cool_Type(Set : access Base_Set.Set) is limited_private; procedure Massage(CT : in out Cool_Type; New_Set : Base_Set.Set); ...
end Layered_Abstraction;
Now if we want to define a set type and provide the pre-instantiated signature for it, we run into trouble:
generic type Elem is private; with function Hash(El : Elem) return Integer; package Hashed_Sets is type Set is private; function Union(Left, Right : Set) return Set; ...
package Signature is new Set_Signature(Elem, Set); private type Set is record ... end record; end Hashed_Sets;
The problem is that we can't do the instantiation of Set_Signature where we would want to do so, because the instantiation freezes the type "Set" prematurely.
A similar problem occurs when a type wants to include a pointer to a container based on the type being defined. For example:
package Expressions is type Expr_Ref is private;
package Expr_Sequences is new Sequences(Expr_Ref); -- Freezing trouble here! type Seq_Of_Expr is access Expr_Sequences.Sequence;
function Operands(Expr : Expr_Ref) return Seq_Of_Expr;
...
private type Expression; -- completion deferred to body type Expr_Ref is access Expression; end Expressions;
Here we have a case where we want to instantiate a generic using a private type, and use the results of the instantiation as the designated type of an access type, which is in turn used as a parameter or result type of an operation on the private type.
Unfortunately, we can't instantiate the "Sequences" generic with Expr_Ref, since it is private.
!proposal
(See summary.)
!wording
Add to 12.3(2):
generic_instantiation ::= ... | abstract_package_instatiation
New section:
12.3.1 Partial Package Instantiation
An abstract package instantiation can be used to declare an abstract view of a package instance. A corresponding (concrete) package instantiation provides the concrete view of the instance. In contrast to a concrete instantiation, the actual parameters to an abstract package instantiation may be private types or extensions prior to their full definition, allowing mutual dependence between a type defined within an instance and the full definition of its actual parameter types.
Syntax
partial_package_instantiation ::= package defining_identifier is new generic_package_name generic_actual_part with private;
Legality Rules
A partial_package_instantiation declares a partial instance; such a declaration is allowed only as a declarative_item of the visible or private part of a package, and it requires a completion. The completion of an partial_package_instantiation shall be a (full) package instantiation, and shall appear later within the private part of the enclosing package.
The generic_package_name shall denote a generic package (the template for the partial instantiation). The completion shall declare an instance of the same template; the partial instance provides a partial view of this instance. The actual parameters of the completion shall match the corresponding actual parameter of the partial instantiation, whether the actual parameter is given explicitly or by default.
The rules for matching of actual parameters between the completion and the abstract instantiation are as follows:
* For a formal object of mode IN the actuals match if they are static expressions with the same value, of if they statically denote the same constant, or if they are both the literal NULL.
* For a formal subtype, the actuals match if they denote statically matching subtypes.
* For other kinds of formals, the actuals match if they statically identify the same entity.
AARM NOTE: We considered using full conformance rules here instead of
formal-package-ish matching. However, we wanted to share the rules with formal packages, and it seemed simpler to just define the particular matching rules needed between instantiations.
Static Semantics
The visible part of the partial view includes the first list of basic_declarative_items of the package_specification. In addition, for each actual parameter that is not required to match, a copy of the declaration of the corresponding formal parameter of the template is included in the visible part of the partial view. If the copied declaration is for a formal type, copies of the implicit declarations of the primitive subprograms of the formal type are also included in the visible part of the partial view.
The declarations within an abstract instance provide views of the entities declared by the corresponding declaration within the concrete instance. Prior to this corresponding declaration, certain restrictions apply to the use of these views (see 13.14). After the corresponding declaration, these views are the same as those defined by this corresponding declaration. Prior to the full definition of the type in the concrete instance, a type declared within an abstract instance is not completely defined.
Dynamic Semantics
Elaborating a partial_package_instantiation has no effect.
AARM NOTE: We considered requiring evaluation of the actuals here, but
that would disallow passing deferred constants prior to their completion. Also see the freezing rules, where partial instantiations are defined to not cause freezing.
Change 13.14(1) [suggested presentation improvement]:
... The Legality Rules [forbid certain kinds of uses of an entity in the region of text where it is frozen] {require that any declarative_item or pragma that might affect the representation of an entity occur prior to it becoming frozen}.
Change 13.14(5):
* The occurrence of a generic_instantiation {other than a partial_package_instantiation} causes freezing{, no later than at the end of the instantiation}; ...
AARM NOTE: When the definition of a composite type contains
a component whose type is defined by an earlier partial_package_instantiation, and the "full" instantiation takes the composite type as a formal, we don't want the composite type frozen until the end of the full instantiation, by which point the component's type will be completely defined. However, the composite type might be frozen earlier within the instantiation, if some sort of freezing reference is made to it, such as taking the 'Size of the formal before completing the definition of the (component's) type defined by the instantiation.
Change 13.14(8/1):
... An object name or nonstatic expression causes freezing where it occurs, unless the name or expression is part of a default_expression, a default_name, {a partial_package_instantiation,} or a per-object expression of a components's constraint, in which case[,] the freezing occurs later as part of another construct.
Add after 13.14(18):
An entity with a view defined by a declaration within a partial instance shall not be frozen prior to the occurrence of the corresponding declaration in the concrete instance.
AARM NOTE: Even after this corresponding declaration, other rules
may still disallow freezing, but these are the "normal" freezing rules.
!example
package P is
type A is private;
package Inst is new G(A, X 3) with private; -- partial instantiation
private
type A is record X : Inst.B; end record;
package Inst is new G(A, X, 3); -- completion of partial instantiation
end P;
!discussion
It is a frustrating limitation to the use of generics, particularly as containers and signatures, that they cannot be instantiated using a private type prior to its completion. It is relatively common where a type directly or indirectly contains a subcomponent that gives access back to an object of the enclosing type. When using generics to provide abstraction, access types are often buried within the abstraction rather than making them a visible part of the abstraction. When taking this approach to implement, for example, a set of objects, it is then perfectly reasonable for a type T to include as a component a type representing a "set" of type T. However, the current restrictions on generics make this impossible.
The other important use of an instantiation where the actual is a private type is for "signature" generics. Such generics allow an abstraction to be "bundled" up as an instance of a single generic, and then used as the actual package for a formal package parameter in a subsequent instantiation. Unfortunately, if the signature instantiation cannot itself be part of the visible part of the original generic defining the abstraction, then it becomes much less convenient, and ultimately much less useful. The instantiator of the generic needs to separately instantiate the signature, so that the writer of the generic has no clear way to specify that the generic is declaring an abstraction that is consistent with the signature.
For example, if one establishes a "Map" signature, it would be natural for the Hashed_Map generic and the Ordered_Map generic to both include instantiations of the Map signature within their visible part. However, the rule disallowing instantiations using private types prior to their completion, makes this impossible.
Both of the above problems are solved by this partial instantiation proposal.
During the Ada 9X process, we observed that there is a relationship between generic formal parameter declarations and the kinds of partial views that you would like to declare in the visible part of a package. In the generic, the actual parameter "completes" the formal, whereas in the package, the full definition in the private part "completes" the partial definition given in the visible part. This proposal is essentially taking what is provided by formal package parameters in a generic, and making an analogous capability available in a non-generic package. Note that we require that all parameters be specified in the partial instantiations. We considered allowing partial parameter specification analogous to what is permitted with formal packages, but this seemed to add significant implementation complexity without significant benefit.
One concern which arose during review of this proposal was that if there are multiple components within a composite type each of which requires its own instantiation taking the composite type as an actual, at most one of them can be a "direct" component -- the others must be of an access type. That is because the first "full" instantiation needed for one of the component types will freeze the composite type, and thence freeze all the (direct) component types. The conclusion was that this was not a severe limitation, as using the result of an instantiation as a direct component type was in some sense "breaking" privacy, since it was assuming that the generic defining the component type did not embed an instance of the formal type directly within it.
For example, it is possible that a type produced by an instantiation Generic_Set(T) might produce a set type that embedded at least one instance of T itself. If we then tried to use this set type as a direct component of T we would be violating the rule that disallows a type having an instance of itself as a component. On the other hand, using "access set_of_T" for the component of T would always be safe.
In the case where the author of the generic defining the component type is also the author of the composite type definition, and there is presumed close linkage between the two, this proposal still allows the direct embedding for one such component type.
No similar problem exists for signature packages, as these typically do not define new types. For such packages, the key feature is to be able to expose the instantiation while keeping the type itself private. It has been noted that there are other times where it would be convenient to include non-signature instantiations within the package defining a private type, even if the instantiation doesn't define any types used in the full definition of the private type. These could generally have been placed in child packages, but that may not be what the programmer preferred, and hence this proposal gives additional flexibility in structuring a system.
--!corrigendum 13.14(05)
!ACATS test
An ACATS test should be created for this feature.
!appendix

From: Tucker Taft
Sent: Thursday, September 23, 2004  5:00 PM

Here is round 4 on AI 359. [Editor's note: This is version /02 of the AI.]
It is what we discussed in Madison.  I have provided the wording.
Comments welcome.

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

From: Dan Eilers
Sent: Thursday, September 23, 2004  6:14 PM

Tuck proposed:
>   package Inst is new abstract G(A, others => <>); -- abstract instantiation

I am uncomfortable with this proposed new overloading of "abstract",
because to me, abstract connotes "meta" rather than "partial".
I would rather use "limited new" as a partial instantiation,
analogous to "limited with" as a partial with.  In both cases
we are solving a circularity problem using a partially introduced
package.

So you would say:
    package Inst is limited new G(A, others => <>); -- partial instantiation


>           We have adopted the term "abstract" and "concrete" to match
> the chosen syntax, but it is essentially analogous to the partial/full
> view notion.

We would no longer need to describe this feature using abstract/concrete
just to match the chosen syntax, but could use the more natural partial/full
descriptive terms.

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

From: Randy Brukardt
Sent: Thursday, September 23, 2004  6:55 PM

> I am uncomfortable with this proposed new overloading of "abstract",
> because to me, abstract connotes "meta" rather than "partial".
> I would rather use "limited new" as a partial instantiation,
> analogous to "limited with" as a partial with.  In both cases
> we are solving a circularity problem using a partially introduced
> package.

We specifically considered this syntax at the meeting, and the use of
"abstract" felt  more confortable to the ARG. I think there were two reasons
for that:
  -- This is a very different view than the limited view of a package, so
the use of "limited" is misleading. (I had originally suggested actually
using the "limited" view here, but that was thought to be overly limiting.)
  -- The "abstract" terminology is more comfortable for uses outside of the
defining package. In that case, the view is essentially the same as the full
view (you can't really tell the difference). A limited view is more
restrictive.

We also considered using a new keyword here, but that didn't seem to have
any obvious advantages over abstract.

...
> We would no longer need to describe this feature using abstract/concrete
> just to match the chosen syntax, but could use the more natural
partial/full
> descriptive terms.

That certainly wouldn't follow from the use of the keyword limited. If you
say limited, you should get a limited view. If you want to talk about
partial views, you need to use a keyword that reflects that (such as
"private" or "partial"). "private" seemed too confusing, since it can also
be used in front of "package" to mean something different (for compilation
units).

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

From: Pascal Leroy
Sent: Friday, September 24, 2004  7:51 AM

It seems to me that if we believe that this problem is worth solving, we
should also allow abstract instantiations of generic subprograms.
That's because the resulting (nongeneric) subprogram may be used as an
actual parameter to an abstract package instantiation.

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

From: Tucker Taft
Sent: Friday, September 24, 2004  8:23 AM

This hardly seems worth it, given the ability to declare
a subprogram and then define it via a renaming-as-body of
a generic instantiation.  We don't have formal subprogram
instantiations in generics, perhaps for the same reason.

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

From: Tucker Taft
Sent: Friday, September 24, 2004  8:35 AM

Oops, I mistyped my own syntax in the example...

> ...
> !example
>
>     package P is
>
>         type A is private;
>
>         package Inst is new abstract G(A, others => <>); -- abstract instantiation

Should be: package Inst is abstract new G(A, others => <>);

This order is consistent with type extension syntax,
which seems a good thing.

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

From: Robert A. Duff
Sent: Friday, September 24, 2004  2:46 PM

Tuck said:

> Here is round 4 on AI 359.  It is what we discussed
> in Madison.  I have provided the wording.
> Comments welcome.

I like it.

Dan said:

> I am uncomfortable with this proposed new overloading of "abstract",

I found it a bit odd at first, too, but if you think of it as similar
to the "abstract" that comes at the start of academic papers, I think it
makes sense.  Anyway, I *really* don't want an argument over the syntax
to derail the proposal.  I'll write "limited" or "abstract" or anything
else you want -- so long as I get to pass private types to generics.
I wouldn't mind "is private new" either -- but I'm happy to go along
with what the meeting decided.

Pascal said:

> It seems to me that if we believe that this problem is worth solving,

I certainly think so!

>...we
> should also allow abstract instantiations of generic subprograms.
> That's because the resulting (nongeneric) subprogram may be used as an
> actual parameter to an abstract package instantiation.

That's a good point.  But please, drop that idea if it causes any
extra trouble.  The workarounds aren't so bad for subprograms.

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

From: Dan Eilers
Sent: Friday, September 24, 2004  4:19 PM

> I found it a bit odd at first, too, but if you think of it as similar
> to the "abstract" that comes at the start of academic papers, I think it
> makes sense.  Anyway, I *really* don't want an argument over the syntax
> to derail the proposal.  I'll write "limited" or "abstract" or anything
> else you want -- so long as I get to pass private types to generics.
> I wouldn't mind "is private new" either -- but I'm happy to go along
> with what the meeting decided.

How essential is it that the partial instantiation is allowed to include
some of the actual parameters?
If this isn't essential, then you wouldn't need any keyword, and
could just say:

    package Inst is new G(<>); -- partial instantiation

where the "<>" is what distinguishes this as a partial instantiation,
analogous to a generic formal package declaration.

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

From: Tucker Taft
Sent: Friday, September 24, 2004  4:36 PM

Using these "non-freezing" (lukewarm? ;-) instantiations for
signatures requires that the actual parameters be provided.
I had also considered using the presence of "<>" to
indicate the "non-freezing" nature, but that only
makes sense for an instantiation that could be
declared in the private part.  For an instantiation
that is visible outside the package, it will usually be
important to "know" what are at least some of the actuals.

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

From: Tucker Taft
Sent: Friday, September 24, 2004  4:43 PM

Note that the original proposal had "with package Inst is new G(...);"
which remains an option in my mind.  Pascal found the "with"
odd in the middle of a package, but I pretty quickly
got used to it, and it makes the connection with formal
packages very obvious.  It also reminds me of the syntax
of various functional languages that permit "let X = 3 in ..."
pretty much anywhere.  So in my mind I started reading the
original proposed notation as "with package Inst being an instantiation
of G in ..." or "assume package Inst is some instantiation
of G in ...".  I suppose if "assert" were a reserved word
we could write "assert package Inst is new G(...);".

Reading "with" as "assert" or "assume" or "let" doesn't seem
that much of a stretch in my mind.

For what that's worth...  ;-)

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

From: Randy Brukardt
Sent: Friday, September 24, 2004  5:10 PM

> How essential is it that the partial instantiation is allowed to include
> some of the actual parameters?

I find it completely necessary. What is unnecessary in my view is the
ability to omit  parameters (although allowing that helps in various ways,
such as not requiring complex conformity rules).

For instance it is common to define a node and a list of nodes in package.
If you wanted to do that with the containers library, you'd write something
like:

   package P is
       type Node is private;
       package Node_Lists is abstract new
           Ada.Containers.Doubly_Linked_Lists (Node);

       -- Primitive operations on Nodes and Lists.List.

   private
       ...
   end P;

This would allow the exported type to have the full set of list operations
available to clients of the package. If the actuals were not known, you
wouldn't be able to use the type, because you couldn't have type matching
between Node and Node_Lists.List. (For instance, Node_Lists.Element would
return an unknown type.)

If you wanted to hide the List implementation, that wouldn't be a problem,
but if you want to expose the listy-ness, you need to know the types.

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

From: Dan Eilers
Sent: Friday, September 24, 2004  5:20 PM

> Using these "non-freezing" (lukewarm? ;-) instantiations for
> signatures requires that the actual parameters be provided.
> I had also considered using the presence of "<>" to
> indicate the "non-freezing" nature, but that only
> makes sense for an instantiation that could be
> declared in the private part.  For an instantiation
> that is visible outside the package, it will usually be
> important to "know" what are at least some of the actuals.

Is it essential that outside the package, the actuals that
weren't specified in the partial instantion won't be visible?

In other words, would it work to treat:

      package Inst is new G(<>); -- partial instantiation

as if all the actuals subsequently provided in the full
instantiation were in fact also mentioned in the partial instantiation?

The precedent being that it is OK for some details of a private part
to "leak", such as the sizes of private types.

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

From: Tucker Taft
Sent: Friday, September 24, 2004  7:29 PM

> In other words, would it work to treat:
>
>       package Inst is new G(<>); -- partial instantiation
>
> as if all the actuals subsequently provided in the full
> instantiation were in fact also mentioned in the partial instantiation?

That sure sounds like a kludge to me.

> The precedent being that it is OK for some details of a private part
> to "leak", such as the sizes of private types.

That is a very different kind of leakage, as it only
applies in representation clauses, which are clearly
talking about the "physical" interface rather than
the "logical" interface.  Everything associated with
the "logical" interface to a package should be in the
visible part.

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

From: Randy Brukardt
Sent: Friday, September 24, 2004  7:58 PM

> In other words, would it work to treat:
>
>       package Inst is new G(<>); -- partial instantiation
>
> as if all the actuals subsequently provided in the full
> instantiation were in fact also mentioned in the partial instantiation?

I think I can hear the scream from Mr. Private all the way from Paris. :-)

Ada has a very clear principle that legality rules and static semantics
never break privateness. That is, the legality of client code does not
depend on the contents of the private part.

OTOH, dynamic semantics (type conversions, by-copy vs. by-reference, 'Size,
etc.) are allowed to break privateness so that the fact that something is
private has no effect on the dynamic semantics. (This principle is slightly
compromised by AI-363 in order that the specification "contract" is adhered
to; that seems better than breaking the contract in perfectly following the
semantics of non-private types.)

As I understand it, at least one compiler depends heavily on those
principles; and "leaking" privateness that affects legality rules is simply
not going to fly. Anywhere.

Anyway, the syntax isn't that big of a deal (although I'd rather forget the
capability of not specifying some or all of the parameters -- it's not worth
the complication in implementation, and we no longer have any real
similarity to formal packages -- which is good, because I don't think anyone
understands them). The real trouble will come from the semantics, and I'd
rather spend my time there.

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

From: Robert Dewar
Sent: Saturday, September 25, 2004  6:45 AM

> Note that the original proposal had "with package Inst is new G(...);"
> which remains an option in my mind.  Pascal found the "with"
> odd in the middle of a package

I do too

, but I pretty quickly
> got used to it, and it makes the connection with formal
> packages very obvious.

I am not sure I would get used to it but you never know

   It also reminds me of the syntax
> of various functional languages that permit "let X = 3 in ..."
> pretty much anywhere.

Not really, the obvious parallel to LET is a DECLARE block
and this really seems different.

It is a bit like the Pascal WITH, and I definitely agree
that the use of ABSTRACT is confusing.

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

From: Robert A. Duff
Sent: Saturday, September 25, 2004  10:13 AM

> It [partial insantiations] is a bit like the Pascal WITH...

I don't understand this analogy.  To me, Pascal's "with" is like Ada's
"use" (except it's for records instead of packages, and Pascal's "with"
is rife with Beaujolais effects).  Please explain.

I presume you're talking about Pascal, the language designed by Wirth,
and not Pascal Leroy, esteemed chair of ARG.

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

From: Pascal Leroy
Sent: Monday, September 27, 2004  2:49 AM

Dan wrote:

> I am uncomfortable with this proposed new overloading of
> "abstract", because to me, abstract connotes "meta" rather
> than "partial".
>
> We would no longer need to describe this feature using
> abstract/concrete just to match the chosen syntax, but could
> use the more natural partial/full descriptive terms.

I too was uncomfortable with this usage of "abstract", as it really has
nothing to do with the other usages for that word in the language (the
types and subprograms exported by this instantiation are _not_ abstract).

I agree that, if we forget syntax for a minute, the correct way to think
of this construct is as a partial view of the instantiation, as all the
entities it exports are partial views.  So the nonterminal should ideally
be named partial_package_instantiation, and the syntax should reflect
this.

Bob replied:

> I found it a bit odd at first, too, but if you think of it as
> similar to the "abstract" that comes at the start of academic
> papers, I think it makes sense.  Anyway, I *really* don't
> want an argument over the syntax to derail the proposal.
> I'll write "limited" or "abstract" or anything else you want
> -- so long as I get to pass private types to generics.

I disagree with this assessment.  In general, experience has proven that,
for a proposal to make progress, it is important to find a "good" syntax.
Otherwise we keep coming back to the syntax issue.  More importantly, the
syntax should really reflect the underlying semantics.  As I said above, I
see nothing "abstract" in these instantiations, so the fact that the
syntax resembles that of abstract derived types is just confusing.  A
syntax that would be based on "limited" would be confusing too, as these
instantiations don't export a limited view.  The word that we consistently
use throughout the language to express that we have a partial view is
"private", so I believe that we should try to use that word here too.

So without further ado, let me propose a syntax that mimics that of
private extensions:

	package Inst is new Gen (Param, <>) with private;

This one has the advantage of conveying the notion that the instantiation
gives a partial view, and that more information will be provided later in
the private part.  It is also sufficiently similar to existing syntax that
it should be easy to learn.  And it is sufficiently different from the
syntax for private library units that no confusion is possible between the
too.

The perfect solution, isn't it? ;-)

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

From: Robert A. Duff
Sent: Monday, September 27, 2004  8:44 AM

> I disagree with this assessment.  In general, experience has proven that,
> for a proposal to make progress, it is important to find a "good" syntax.

True, but experience has also shown that proposals sometimes get killed
for being "too complex", where the measure of complexity is "how long
and hard we have argued about it".  I was trying to express that at this
point, I am willing to go along with whatever syntax some folks in some
meeting decided on.  However, ...

> 	package Inst is new Gen (Param, <>) with private;

I like it.

> The perfect solution, isn't it? ;-)

Yes, it is perfect.  Now, everybody else, please just say "yes".  ;-)

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

From: Gary Dismukes
Sent: Monday, September 27, 2004  10:57 AM

> > 	package Inst is new Gen (Param, <>) with private;
>
> I like it.

I also like that syntax.  Even though I found the "abstract" syntax
acceptable at the time we voted on it, I still felt that somehow
the 'private' keyword would be more appropriate.  Pascal's latest
proposal integrates 'private' nicely (not to mentioning also
bringing along the 'with' of Tuck's original suggestion, in
a nicer syntactic position;-).

> > The perfect solution, isn't it? ;-)
>
> Yes, it is perfect.  Now, everybody else, please just say "yes".  ;-)

Certainly close enough for my taste, so "yes"!

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

From: Tucker Taft
Sent: Saturday, September 25, 2004  7:57 AM

Several times Randy has suggested we drop the "<>"
aspect of abstract instantiations.  That would seem
to simplify the description and the implementation.
Should we go that direction?

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

From: Robert A. Duff
Sent: Saturday, September 25, 2004  9:57 AM

Well, what do we lose?

And are these things analogous to formal packages or not?

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

From: Pascal Leroy
Sent: Monday, September 27, 2004  2:56 AM

As an implementer, I am tempted to side with Randy, as these boxy
instantiations are probably going to make the compiler's job harder.

However, as a user, I think it would be a mistake.  The reason is that you
will then have to move to the visible part some auxiliary declarations
that would otherwise remain hidden in the private part.  No big deal if
the declaration is a mere named number, but things become hairy if it's a
complicated type declaration.  That restriction would seriously weaken the
architectural benefits of the proposal, to the extent that I am not sure I
would support it (the proposal).

In general, I am wary of restrictions that are there for the sole purpose
of helping implementers: many times they do not simplify implementations
significantly, but they impose a real burden on users.

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

From: Randy Brukardt
Sent: Monday, September 27, 2004  4:51 PM

I agree when you're talking about restrictions. But this isn't a
"restriction"; you're asking to expand a feature far beyond its intended
purpose. That came about because Tucker tried to draw a parallel with formal
packages. But since that parallel is illusory at best, I don't think many
programmers will ever notice any "restriction".

I understand your concerns about visibility, but I think it is misguided.
Since client's of your package will have a name for the "hidden" formal
anyway, you are essentially going to be making that information visible
anyway. I'd rather that the information leak be explicit.

Moreover, the entire point of this feature is to be able to make things
visible (instantiations) that otherwise could not be. Complaining that you
can't hide parts of things you are trying to make visible is rather odd. If
you want to hide it, don't put the instantiation in the visible part!

I'm certain that <> parameters in the instantiation aren't worth it; hardly
anyone would use them (very few Ada programmers write formal packages), and
it would be constant source of bugs in compilers and the language
definition. (Formal packages certainly have been.) They're just not worth
it.

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

From: Robert A. Duff
Sent: Monday, September 27, 2004  7:15 PM

I find the above arguments persuasive.  I am one of the main proponents
of solving this problem, and I never particularly wanted to hide some of
the parameters.  I just want to be able to pass private types (and, I
suppose, deferred constants) to instantiations.

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

From: Pascal Leroy
Sent: Friday, October 1, 2004  3:44 AM

I realize that I never replied to Randy's comments about boxy
instantiations:

> I understand your concerns about visibility, but I think it
> is misguided. Since client's of your package will have a name
> for the "hidden" formal anyway, you are essentially going to
> be making that information visible anyway. I'd rather that
> the information leak be explicit.

That's an excellent point.  At the meeting I was uncomfortable with the
notion that the boxy case would give you a way to peek into the private
part, in some sense.  It's much better to force the user to explicitly
move into the visible part whatever actuals they need.  These can be
private types or deferred constants if information hiding is required.

So I say: drop the boxy instantiations, this makes the proposal cleaner
and simpler to implement.

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

From: Tucker Taft
Sent: Friday, October 1, 2004  6:56 AM

If we drop the "boxy" parameters, are we still content
with the use of "with private" at the end of the instantiation
to signal that it is a "forward"/"partial"/"abstract" instantiation?

I can rationalize the "with private" by meaning that it "allows private types"
as actuals.  On the other hand, "abstract new" works for me,
as does "with package P is ...".  I await the decision of the
group.

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

From: Pascal Leroy
Sent: Friday, October 1, 2004  7:48 AM

> I can rationalize the "with private" by meaning that it
> "allows private types" as actuals.

I prefer to rationalize by saying that the instantiation exports
entities that work more-or-less like private types (intense hand-waving
here).

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

From: Gary Dismukes
Sent: Friday, October 1, 2004  11:59 AM

I find "with private" a little less compelling once boxy instantiations
are removed, but I still prefer it to the other choices.

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

From: Robert I. Eachus
Sent: Friday, October 1, 2004  2:24 PM

> I can rationalize the "with private" by meaning that it "allows private
> types" as actuals.  On the other hand, "abstract new" works for me,
> as does "with package P is ...".  I await the decision of the
> group.

Let me suggest a different approach, and you implementers can tell me if
it creates problems.  Don't mark the externally visible template at
all.  The difference from regular instantiations is that there is a
completion in the private part, right?  All I can see that the syntactic
sugar adds is that freezing issues with regular instantiations can be
flagged at  the point of the error instead of at the end of the private
part.  It would probably be nice to have a syntactic flag in the
completion, but that is in the private part and won't impact nearly as
many users.  There is no contract issue, since the issues are all
internal to the package specification and the private part.

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

From: Randy Brukardt
Sent: Friday, October 1, 2004  2:24 PM

We've discussed variations on that ad-nausum. Please read the other three
alternatives of the AIs and all of the minutes on this issue to see what's
been covered already.

In a nutshell, it is agreed that if the semantics are very different, it
should look different, both for the readers of the text, and for the
implementation. Our essentially one-pass compiler design could not handle
two different semantics for the same program text - it would require a
complete redesign of the way units are compiled.

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

From: Tucker Taft
Sent: Sunday, October 3, 2004  6:54 AM

After more thought, I came to realize that we really
do have a "partial" view of the instantiation.  That
is because we are building it on a partial view of
the actuals, and the instance is clearly dependent
on the actuals.  When we later instantiate with the
full view of the actuals, we can get something quite
different.  For example, if the generic declares an
array-of-formal-type-T, if we instantiate it with
a private type, clearly it will not be considered
an array of discrete.  But in the private part, where
we instantiate with the full view, it might be a discrete
type, or even boolean, so the array-of-formal-T might
have quite different properties.

All of which makes me more content calling this a partial
instantiation, which provides a partial view of the
instance, defined by the partial view of the actuals
provided at the point of the instantiation.

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

From: Robert I. Eachus
Sent: Sunday, October 3, 2004  7:55 PM

I think for the reasons that Tucker explained, "with private" fits
nicely, there may be things added to the instantiation in the private
part, that will not be visible outside the package heirarchy.

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


Questions? Ask the ACAA Technical Agent