Version 1.2 of ai12s/ai12-0257-1.txt

Unformatted version of ai12s/ai12-0257-1.txt version 1.2
Other versions for file ai12s/ai12-0257-1.txt

!standard 4.1.3(9.1/2)          18-02-22 AI12-0257-1/01
!standard 4.1.3(9.2/2)
!class Amendment 18-02-22
!status Hold by Letter Ballot (8-0-3) - 18-05-07
!status work item 18-02-22
!status received 18-03-20
!priority Very_Low
!difficulty Medium
!subject Generalize prefix views
!summary
Prefixed views are allowed on untagged private types.
!problem
Ada users often are surprised that prefixed views cannot be used for abstractions that aren't tagged. That can lead to abstractions being declared tagged for no reason other than wanting prefixed notation (argubly, this was the case with the containers).
!proposal
We have to decide how to handle prefixed views on full types of untagged private types.
It would be unusual if the prefixed view wasn't allowed at all (unless the full type was tagged or access-to-tagged). That would mean that moving an a subprogram previously defined in client code into the package of an abstraction could fail to compile if it used any prefixed views.
However, since allowing prefixed views on access types would be incompatible (and complex), we can't allow that to be required.
Probably the best rule would be something like a prefixed view is allowed on an untagged private type, or an untagged non-access type that is the full type of a private type.
We'd still have the weird case for access types; we could allow prefixed views on those so long as they don't designate a tagged type and so long as the dereferences of the access values aren't considered -- but that's nearly as weird as not allowing prefixed views there at all.
!wording
** TBD.
!discussion
Unfortunately allowing prefixed views on all types would be incompatible.
Ptr.Id
could mean Id(Ptr) or Id(Ptr.all). Currently, Id(Ptr) is not considered, so allowing prefixed views on all types could make some currently legal calls ambiguous.
!ASIS
[Not sure. It seems like some new capabilities might be needed, but I didn't check - Editor.]
!ACATS test
ACATS B- and C-Tests are needed to check that the new capabilities are supported.
!appendix

From: Tucker Taft
Sent: Saturday, January 20, 2018  10:32 AM

> 0) Should Big_Integer and (especially) Big_Rational be visibly tagged?
> 
> If so, then we can use prefix notation on functions like Numerator and 
> Denominator. We could also consider deriving both versions (usual and
> bounded) from an abstract ancestor.
> ...

Somewhat off topic, but should we consider generalizing prefix notation to all 
types, or at least all private types?  I can't remember any reason why prefix
notation really needs tagged types to make sense.  Now that we have "use all
type" clauses, we already know how to make all the relevant (primitive)
operations directly visible.  Why not allow prefix notation for all such
operations?

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

From: Gary Dismukes
Sent: Saturday, January 20, 2018  7:40 PM

It seems reasonable to me to consider such an extension.

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

From: Randy Brukardt
Sent: Saturday, January 20, 2018  7:37 PM

My recollection was that access types caused problems, because of the implicit
indirection. In particular, does

    Ptr.Id

mean Id(Ptr) or Id(Ptr.all)? By making the rules tagged only, we side-stepped
that.

I'd have to look up the minutes/notes on the prefixed notation to see the exact
cases that caused trouble. (The implicit 'Access might also cause issues.) I
know the issues were bothersome enough to restrict them to tagged types as a
last resort (your original proposal allowed them on all types).

Blame Baird, as usual. ;-)

Note that allowing all types now would in fact be incompatible, if Ptr and
Ptr.all both had an Id primitive operation. Currently, the Ptr operation isn't
considered, so changing the rules could make some legal calls ambigious.

Allowing private only was considered, but it would be weird if clients could
use prefixed notation but the implementation of some type could not.

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

From: Randy Brukardt
Sent: Saturday, January 20, 2018  8:17 PM

> It seems reasonable to me to consider such an extension.

You are willing to introduce an incompatibility and/or visibility hole for
that??

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

From: Gary Dismukes
Sent: Sunday, January 21, 2018  1:45 AM

Probably not, it was a quick reply to Tucker's message just indicating that it
might be worth considering his suggestion, without thinking more deeply about
it at the time (whereas you did).  It did occur to me that there might be
incompatibilities.  In any case, I hadn't yet seen your message at the time I
posted that.

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

From: Tucker Taft
Sent: Sunday, January 21, 2018  2:11 PM

...
> Note that allowing all types now would in fact be incompatible, if Ptr 
> and Ptr.all both had an Id primitive operation. Currently, the Ptr 
> operation isn't considered, so changing the rules could make some calls
> ambigious.

Good point.  So access types should probably be left out of the picture,
except in service to other types via access parameters.
 
> Allowing private only was considered, but it would be weird if clients 
> could use prefixed notation but the implementation of some type could not.

This doesn't seem so odd to me now, in part because several of the features
I have been working on recently will probably have similar rules, where you
can use a notation when you only see the partial view, but when you see the
full view the notation is unavailable.  That doesn't seem so bad.  When you
are defining an abstraction, you often don't want the abstraction being used
"inside" because it might lead to infinite recursion, or just some confusion.
On the other hand, when looking at it from the outside, you aren't distracted
by the details of the implementation, and can focus purely on the abstract
behavior, where the "special notation" whatever it is makes sense.  Literals
and container aggregates, in particular, will probably be unavailable when you
can see the full type if the full type happens to be something that has its
own literals and/or aggregates.

The term "partial view" might better be something like "abstraction view" or
"external view" to emphasize how different it might be from the full/internal
view.  It is not just a subset of the full view, but rather a potentially
quite different view.

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

From: Randy Brukardt
Sent: Monday, January 22, 2018  3:49 PM

This still seems weird to me.

The literal/aggregate case is one of hiding: if the full type has literals or
aggregates, then the ones of the private view are hidden. But if the full type
doesn't have those things, the literals or aggregates can be used on the full
type as well. That would make perfect sense, and it wouldn't be the case that
the operation "disappeared" so much as being "replaced". (That happens in
other ways as well, so it seems normal.)

But in this case, you'd have an capability that would unconditionally
disappear on the full type. There is nothing like that in Ada currently. And
we don't do anything currently to prevent infinite recursion in package bodies
(spoken as someone who has a lot of experience with implementing "+", "=", and
other overridden operations in terms of themselves); it's strange to suddenly 
care about that 40 years too late.

> The term "partial view" might better be something like "abstraction 
> view" or "external view" to emphasize how different it might be from 
> the full/internal view.  It is not just a subset of the full view, but 
> rather a potentially quite different view.

I suppose that could work, but it would take a lot of getting used to, as it
certainly is not the current state of affairs.

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


Questions? Ask the ACAA Technical Agent