Version 1.4 of ai05s/ai05-0101-1.txt
!standard E.2.2(14/2) 08-11-13 AI05-0101-1/04
!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 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 an remote access-to-classwise (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 RCI subprograms and 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: I intend to delete the access parameter portion above 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 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 makes 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 implictly 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 makes 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.
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 Distributed_P;
package body P is
Foo : aliased T;
function Local_Call return access T is
begin
--
return Foo'access; --
end Local_Call;
function Remote_Call (Controlling_Operand : access T) return access T is
pragma Unreferenced (Controlling_Operand);
begin
--
return Foo'access; --
end Remote_Call;
end Foo_Pkg;
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;
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;
--
--
Remote : constant Distributed_P.T_Access --
:= Distributed_P.T_Access (P.Remote_Call (My_Foo'access));
begin
--
Distributed_P.Set_Foo (Remote);
declare
--
--
Local : constant Distributed_P.T_Access
:= Distributed_P.T_Access (P.Local_Call);
--
Local2 : constant access P.T := P.Local_Call;
--
--
--
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:
- The primitive subprograms of the corresponding specific limited private
type shall only have access parameters if they are controlling formal
parameters; each non-controlling formal parameter shall support external
streaming (see 13.13.2);
by:
- 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. Each non-controlling
formal parameter and non-controlling result subtype shall support
external streaming (see 13.13.2);
!corrigendum E.2.2(16/1)
Insert after the paragraph:
- 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 (see E.4,
"Remote Subprogram Calls");
the new paragraph:
- 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;
!corrignedum E.2.3(14/2)
Replace the paragraph:
- 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 of a type that does not support external streaming (see 13.13.2);
by:
- it shall not be, nor shall its visible part contain, a subprogram (or
access-to-subprogram) declaration whose profile has a parameter or result
of a type that does not support external streaming (see 13.13.2);
!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