Version 1.7 of ai05s/ai05-0101-1.txt

Unformatted version of ai05s/ai05-0101-1.txt version 1.7
Other versions for file ai05s/ai05-0101-1.txt

!standard E.2.2(14/2)          09-05-30 AI05-0101-1/05
!standard E.2.2(16/1)
!standard E.2.3(14/2)
!standard E.4(7)
!class binding interpretation 08-05-28
!status Amendment 201Z 08-11-26
!status WG9 Approved 09-06-12
!status ARG Approved 5-0-2 08-11-02
!status work item 08-05-28
!status received 06-04-22
!priority Low
!difficulty Medium
!qualifier Omission
!subject Remote functions must support external streaming
!summary
The result type of a remote function must either support external streaming or be a controlling access result type.
A remote function that returns an access result type must have a controlling access result. Such a function returns a value of a remote access-to-class-wide type if the function has any controlling operands. Otherwise, a function without a controlling operand must return an access value that designates an object of a non-remote access type (a local object).
!question
E.2.2(14/2) specifies restrictions applying to the types of non-controlling formals of the primitive operations of the limited private type associated with a remote access-to-classwide (RACW) type. Should the same restrictions be applied to a non-controlling result, to ensure that the returned value can be sent back to the calling partition? (Yes.)
E.2.3(14/2) has similar language for remote call interface (RCI) subprograms and remote access-to-subprogram (RAS) types. Should this clause be augmented to forbid functions returning a type that does not support external streaming? (Yes.)
!wording
Change E.2.2(14/2) as follows (this wording includes the changes of AI05-0060-1):
The primitive subprograms of the corresponding specific type shall only have access parameters if they are controlling formal parameters[;]{. The primitive functions of the corresponding specific type shall only have an access result if it is a controlling access result. E}[e]ach non-controlling formal parameter {and non-controlling result subtype} shall support external streaming (see 13.13.2);
Add a new bullet after E.2.2 (16/1):
* A controlling access result value for a primitive function with any controlling
operands of the corresponding specific type shall either be explicitly converted to a remote access-to-class-wide type or be part of a dispatching call where the value designates a controlling operand of the call;
Change E.2.3(14/2) as follows:
* it shall not be, nor shall its visible part contain, a subprogram (or
access-to-subprogram) declaration whose profile has [an access parameter or] a parameter {or result} of a type that does not support external streaming (see 13.13.2);
AARM Ramification: No anonymous access types support external streaming, so they are never allowed as parameters or results of RCI subprograms.
[Editor's note: The access parameter portion of the wording above was intentionally deleted as it is redundant and including it complicates the wording for little value.]
Change E.4(7) as follows:
[A] {Remote types library units (see E.2.2) and} remote call interface library unit{s} (see E.2.3) define[s] the remote subprograms or remote access types used for remote subprogram calls.
!discussion
Annex E provides adequate rules describing the restrictions for parameters of a remote call, but lacks clarity on describing the restrictions that should be applied to the results of remote function calls. Generally, the same rules should apply, but there are cases that need special consideration.
In the case of a non-controlling function result, the function result has to be streamed from a remote partition, so this should be clearly stated in the rules. However, E.2.2(14/2) and E.2.3 (14/2) only describe rules for parameters of remote subprogram calls; there is no mention of restrictions that apply to a remote function result type.
There is no reason why a non-controlling function result should be treated differently than non-controlling parameters. That is, it only makes sense to allow remote function calls that have a result type that supports external streaming. This rules out non-controlling access result types since anonymous access types do not support external streaming.
Special consideration needs to be given to functions that have a controlling access result however.
E.4 (5) states that a remote subprogram call can be executed as “a dispatching call with a controlling operand designated by a value of a remote access-to-class-wide type.”
3.9.2 (2/2) states that “a controlling operand in a call on a dispatching operation of a tagged type T is one whose corresponding formal parameter is of type T or is of an anonymous access type with designated type T”.
If controlling anonymous access parameters of dispatching subprograms can be designated by a value of a remote access-to-class-wide type, it seems logical that a controlling access result of a dispatching function should be treated the same way: as a result type that can be designated by a value of a remote access-to-class-wide type. Indeed, there does not seem to be any other semantic meaning that could be applied to such an access result returned from a remote function call. It surely must be a value of a remote access-to-class-wide type.
However, 13.13.2 (52/2) states that “an anonymous access type does not support external streaming”, so if we are to allow streaming of a remote access-to-class-wide type as a controlling access result, then special wording will need to be added to the RM to allow this, similar to the wording used to allow streaming of remote access-to-class-wide types for subprogram parameters. The wording should add restrictions that ensure such a result is either explicitly converted to a remote access-to-class-wide type by the caller, or used as a controlling operand of another dispatching call to a remote subprogram.
There is a further distinction that needs to be observed. E.4 (5) stated above that a dispatching function call with a controlling operand is a remote subprogram call. A dispatching function call that does not have a controlling operand is not a remote subprogram call. The controlling access result returned by such a function should be treated as a value of a local anonymous access type. This is enforced by E.2.2 (15) which states “A value of a remote access-to-class-wide type shall be explicitly converted only to another remote access-to-class-wide type” and by E.2.2(16/1) which states that “A value of a remote access-to-class-wide type shall be dereferenced (or implicitly converted to an anonymous access type) only as part of a dispatching call where the value designates a controlling operand of the call”.
These rules make it impossible for a local function to obtain a value of a remote access-to-class-wide type and return it to the caller, because it would have to be implicitly converted from an access-to-class-wide type to an anonymous access-to-specific type of the controlling result, which is not allowed. For the same reason, these rules make it impossible for a remote function to obtain a value of a remote access-to-class-wide type from another partition and return that value to the caller.
The change to E.4(7) is somewhat unrelated but is needed because the existing wording conflicts with other wording already in the standard (E.2.2 (9/3)). E.4(7) says that only remote call interface library units can be used to define remote subprogram calls, but remote types library units also define remote subprogram calls and remote access types for issuing remote subprogram calls.
Here is an example, showing the usage of functions that return remote access types:
package P is pragma Remote_Types;
type T is tagged limited private;
function Remote_Call (Controlling_Operand : access T) return access T; function Local_Call return access T;
private type T is tagged limited null record; end P;
with P; package Distributed_P is
pragma Remote_Call_Interface;
type T_Access is access all P.T'Class;
procedure Set_Foo (Item : T_Access);
function Get_Foo return T_Access; end Distributed_P;
with Distributed_P; package body P is
Foo : aliased T;
function Local_Call return access T is begin -- return Distributed_P.Get_Foo; -- illegal E.2.2 (16/1) return Foo'access; -- OK end Local_Call;
function Remote_Call (Controlling_Operand : access T) return access T is pragma Unreferenced (Controlling_Operand); begin -- return Distributed_P.Get_Foo; -- illegal E.2.2 (16/1) return Foo'access; -- OK
end Remote_Call;
end Foo_Pkg;
package body Distributed_P is
Remote_Foo : T_Access;
function Get_Foo return T_Access is begin return Remote_Foo; end Get_Foo;
procedure Set_Foo (Item : T_Access) is begin Remote_Foo := Item; end Set_Foo;
end Distributed_P;
with P; with Distributed_P;
procedure Test_Function_Access_Return is My_Foo : aliased P.T;
-- 1) Function returns local RACW value that must be explicity converted -- to a RACW Remote : constant Distributed_P.T_Access -- Legal Conversion? (Yes) := Distributed_P.T_Access (P.Remote_Call (My_Foo'access));
begin
-- Send the local RACW off to some remote location Distributed_P.Set_Foo (Remote);
declare -- 2) Function returns local access value that is optionally converted -- to a RACW Local : constant Distributed_P.T_Access := Distributed_P.T_Access (P.Local_Call);
-- 3) Same call as 2) but not converted to a RACW Local2 : constant access P.T := P.Local_Call;
-- 4) First call returns RACW that dispatches to same remote partition -- returning a controlling access result from that partition that -- must be explicitly converted to a RACW Remote2 : constant Distributed_P.T_Access := Distributed_P.T_Access (P.Remote_Call (P.Remote_Call (Distributed_P.Get_Foo))); begin null; end;
end Test_Function_Access_Return;
!corrigendum E.2.2(14/2)
Replace the paragraph:
by:
!corrigendum E.2.2(16/1)
Insert after the paragraph:
the new paragraph:
!corrigendum E.2.3(14/2)
Replace the paragraph:
by:
!corrigendum E.4(7)
Replace the paragraph:
A remote call interface library unit (see E.2.3) defines the remote subprograms or remote access types used for remote subprogram calls.
by:
Remote types library units (see E.2.2) and remote call interface library units (see E.2.3) define the remote subprograms or remote access types used for remote subprogram calls.
!ACATS Test
New B-Tests are needed to check the newly added restrictions.
!appendix

!topic Return type of remote function should support external streaming
!reference Ada 2005 E.2.2(14/2), E.2.3(14/2)
!from Thomas Quinot 08-04-22
!keywords distributed systems, return type, support external streaming
!discussion

E.2.2(14/2) specifies restrictions applying to the types of non-controlling
formals of the primitive operations of the limited private type associated
with an RACW. The same restrictions must be applied to a non-controlling
result, to ensure that the returned value can be sent back to the
calling partition. (The case of controlling access results is an annoying
irregularity since these can't support external streaming (being anonymous
access types). Maybe a special exception should be added for those).

E.2.3(14/2) has similar language for RCI subprograms and RAS types.
This clause should be augmented to forbid functions returning a type that
does not support external streaming.

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

From: Tucker Taft
Sent: Tuesday, April 22, 2008  7:15 AM

Good point about the non-controlling result.
But I don't follow your point about the
controlling access result.  I would have said that a controlling
(non-access) result needs to support external streaming, whereas with
a controlling *access* result, the restriction would be that it *must*
be converted to a RACW upon return, since it can't be a "normal"
access value.

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

From: Thomas Quinot
Sent: Tuesday, April 22, 2008  7:41 AM

> But I don't follow your point about the controlling access result.  I 
> would have said that a controlling (non-access) result needs to 
> support external streaming,

Sounds reasonable, but this is not currently explicit in the RM.

> whereas with
> a controlling *access* result, the restriction would be that it *must* 
> be converted to a RACW upon return, since it can't be a "normal"
> access value.

... and can't support external streaming. Which is why I mentioned we
might need a separate rule explicitly making it compulsory to convert
such a controlling access result to an RACW.

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

From: Brad Moore
Sent: Wednesday, October 15, 2008 10:36 AM	

There seems to be a discrepency in the RM with regards to the types of
library units that can have remote access types.

E.4 (7) "A remote call interface library unit (see E.2.3) defines the
remote subprograms or remote access types used for remote subprogram calls"

E.2.2 (9/3) "A named access type declared in the visible part of a remote
types or remote call interface library unit is called a remote access type."

E.4 Says that only remote call interface library units can have remote
access types, while E.2.2 says that both remote call interface library units
and remote types library units can have remote access types.

It seems to me that E.4 (7) should be corrected to also include remote types
library units.

Ideally this would have been caught and corrected in AI05-0060, but I
believe it is too late to make more changes to that AI. I also had considered
whether this could be corrected in AI05-0101, but this seems to be too
unrelated to the subject of that AI. 

I am thinking it would take a new AI to make this change. Should a new AI
be created, or should I try to get this in to AI05-0101?

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

From: Randy Brukardt
Sent: Wednesday, October 15, 2008  5:10 PM	

> It seems to me that E.4 (7) should be corrected to also include remote 
> types library units.

I suppose, or one could simply delete the statement (it really ought
to be a note, not normative semantics). This is just introductory text
and it generally doesn't have any semantic meaning. It probably should be
marked as redundant (it is not),  as it doesn't seem to express any new
semantics.

> Ideally this would have been caught and corrected in AI05-0060, but I 
> believe it is too late to make more changes to that AI.

That is correct.

> I also had considered whether this could be corrected in AI05-0101, 
> but this seems to be too unrelated to the subject of that AI.

I don't see why. It's subject is really "Things we f***ed up in AI05-0060-1".
We often sneak in other minor changes into bigger AIs.
 
> I am thinking it would take a new AI to make this change. 

Please don't. We really don't need hundreds of trivial AIs to manage -- Adam
forces us to make a lot of them as it is.

> Should a new AI be created, or should I try to get this in to AI05-0101?

Either that, or treat it as an editorial change and have me stick it into
the presentation AI. Whether that is a good idea depends on whether you think
E.4(7) has any semantic content [the original authors seem to have thought so]
-- if it does, it shouldn't be in a presentation AI.

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

From: Brad Moore
Sent: Wednesday, October 15, 2008 10:00 PM	

> I suppose, or one could simply delete the statement (it really ought to be a
> note, not normative semantics). This is just introductory text and it
> generally doesn't have any semantic meaning. It probably should be marked as
> redundant (it is not),  as it doesn't seem to express any new semantics.

My argument against simply deleting the statement is that one shouldn't have to read
section E.2.2, (entitled Remote Types Library Units) to find out something
that pertains to Remote Call Interface Library Units. Having the statement in
section E.4 (entitled Remote Subprogram Calls) at least puts the information in
a place where one might look. Alternatively, a new statement could be added
to section E.2.3 that pertains to Remote Call Interface Library units, but I would
think it is better to minimize the changes,
which is why I suggest we simply modify E.4 (7) to say something like;
 
"[A] {Remote types library units (see E.2.2) and} remote call interface library unit{s}
 (see E.2.3) define[s] the remote subprograms or remote access types used for 
remote subprogram calls."
 
I agree that the statement should be marked as redundant, and possibly converted into a note.
This sounds like something that could be left for Portland and sorted out then, although I
can resubmit AI05-0101 with this wording if you like.
 
>> I also had considered whether this could be
>> corrected in AI05-0101, but this seems to be too unrelated to
>> the subject of that AI.
>
> I don't see why. It's subject is really "Things we f***ed up in
> AI05-0060-1". 
 
To be fair, I have come to the conclusion that AI05-0060 did not break anything.
The wording affected by AI05-0101 and the wording in E.4(7) were broken long
before AI05-0060. I believe you'd have to go farther back in time to find when
wording changes might have been introduced that would have broken the wording for
these sentences, if in fact they they ever did read correctly.
AI05-0060 only improved things by plugging some of the holes and providing
clarification. Unfortunately at the time, we weren't aware of the other bugs
lurking in the wording related to the distributed systems annex, though it would
have been nice to have caught them when we were working on AI05-0060. 
 
>> Should a new AI be created, or should I try to get this in to AI05-0101?

> Either that, or treat it as an editorial change and have me stick it into
> the presentation AI. Whether that is a good idea depends on whether you
> think E.4(7) has any semantic content [the original authors seem to have
> thought so] -- if it does, it shouldn't be in a presentation AI.

I suspect that E.4(7) is probably only there because it covers remote call
interface library units in a logical place. I also note that E.4(7) is older
wording than E.2.2(9/3). Could it be that E.4(7) once was the place
that had the semantic content, but it was later added to E.2.2(9/3)? 
In any case, I see this as redundant to E.2.2(9/3), but provides a better
semantic linkage to the information pertaining for remote call interface
library units. It's sort of a grey area whether this constitutes any
semantic meaning, and since there is already an open AI in that has specific
focus on the distributed systems annex, I am thinking it probably makes more
sense to include in AI05-0101.
 
****************************************************************

From: Randy Brukardt
Sent: Wednesday, October 16, 2008  1:29 PM	

>  I agree that the statement should be marked as redundant, and
>  possibly converted into a note.
>  This sounds like something that could be left for Portland and
>  sorted out then, although I
>  can resubmit AI05-0101 with this wording if you like.

Yes, please do that. Otherwise, we're likely to forget to consider it at the
meeting.

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



Questions? Ask the ACAA Technical Agent