CVS difference for ai12s/ai12-0125-3.txt
--- ai12s/ai12-0125-3.txt 2015/11/24 03:50:43 1.3
+++ ai12s/ai12-0125-3.txt 2016/01/09 00:10:38 1.4
@@ -1,14 +1,16 @@
-!standard 5.2.1(0) 15-10-13 AI12-0125-3/01
+!standard 5.2.1(0) 16-01-08 AI12-0125-3/02
!class Amendment 15-10-13
!status work item 15-10-13
!status received 15-09-22
-!subject Add <<>> as a shorthand for the LHS of an assignment
+!subject Add @ as a shorthand for the LHS of an assignment
-Define <<>, which can be used in the right-hand side of an assignment
+Define @, which can be used in the right-hand side of an assignment
statement as a shorthand for the name of the left-hand side.
@@ -26,119 +28,226 @@
-We define a new symbol, <<>>, which represents a rename of the left-hand
-side of an assignment.
+We define a new symbol, @, the *target name* which represents a constant view
+of the left-hand side of an assignment.
-Add <<>> to Primary in 4.4, with -- See 5.2.1.
+Add after 3.3(21.1/3): [Editor's note: This is the list of items that are
+defined to be constant. Since that list is defined to be exclusive, we have
+to include target_name here.]
+ * a target_name of an assignment_statement when used in the
+ expression of the assignment (see 5.2.1);
+[Editor's note: The "when used in the expression of the assignment" isn't
+strictly necessary, as that is the only place a target_name is allowed. But
+this is a forward reference and a causal reader might interpret this as
+applying to the *variable_*name of the assignment -- which it does not.]
+Add target_name to the syntax of Name in 4.1(2/3).
+[Editor's note: We add a new syntax nonterminal because all of the other
+kinds of name are defined that way, rather than by reference to other
+subclauses as is done for a primary. We try to be consistent within
+a clause, even if the Standard is not consistent for similar constructs.]
Add a new subclause:
- 5.2.1 Target name (<<>>) shorthand
+ 5.2.1 Target name (@) shorthand
- <<>>, known as the *target name* of an assignment statement,
- provides a shorthand to avoid repetition of potentially long
- names in assignment statements.
- Name Resolution Rules
- <<>> has the nominal subtype of the /variable_/name of an
- Legality Rules
- <<>> shall only appear in the expression of an assignment_statement.
- If <<>> appears in the expression of an assignment_statement S,
- and the expression contains any function calls other than those
- to predefined operators or any equality operation of a record
- type, then the /variable_/name of S shall not denote a
- subcomponent that depends on discriminants of an object whose
- nominal subtype is unconstrained, unless the object is known to be
- AARM Note: This is just the renames legality rule; we allow this
- in the case that no user-defined routines can be called, as there
- is no way to change the discriminant in that case. Record equality
- might have composed a user-defined routine, thus it is included
- [Editor's note: This rule could have been omitted. However, it seems
- preferable that any erroneous execution be as explicitly written as
- possible - that is, the names of the components should explicitly
- appear so that a reviewer can clearly see potential danger. That
- seems more important with this proposal as <<>> can appear anywhere
- in an expression, so it could be somewhat hidden if the expression
- is large.]
- Static Semantics
- If <<>> appears in the expression of an assignment statement S,
- then S is equivalent to a local object renaming that declares a
- unique temporary name of the same type as the /variable_/name,
- to be a renaming of the /variable_/name; this is followed by an
- assignment_statement with its /variable_/name being this
- temporary name, and with its expression being the expression of S
- with all of the <<>> names being replaced by the temporary name.
+ @, known as the *target name* of an assignment statement,
+ provides a shorthand to avoid repetition of potentially long
+ names in assignment statements.
- AARM Discussion:
+ Target_Name ::= @
+ Name Resolution Rules
+ Redundant[If a target_name *T* occurs in an assignment_statement *A*, the
+ *variable_*name *V* of *A* is a complete context.] *T* is a constant view
+ of *V*, having the nominal subtype of *V*.
+ AARM The Proof: The complete context rule is formally given in 8.6.
+ Legality Rules
+ A target_name shall only appear in the expression of an
+ Static Semantics
+ If a target_name with nominal subtype *S* appears in the expression of
+ an assignment statement *A*, then *A* is equivalent to a local anonymous
+ procedure having an in out parameter *P* of subtype *S*, with a
+ body being *S* with the *variable_*name being replaced by *P*, and
+ any target_names being replaced by the qualified expression
+ *S*'(*P*); followed by a call on the anonymous procedure with the
+ actual parameter being the *variable_*name of *S*.
+ [Editor's note: We use a qualified expression here to ensure the
+ replacement has the semantics of a constant view. I would have preferred
+ to avoid that (a target_name is a constant view by rule), but just using
+ *P* here is misleading, especially if someone is doing expression
+ analysis after this expansion. We could probably drop the explicit
+ definition of @ as a constant view, since this expansion would have
+ that effect anyway, but it seems valuable to emphasize that to readers.]
+ AARM Reason: This equivalence defines all of the Dynamic Semantics
+ for these assignment statements. We use the parameter to bind the
+ *variable_*name; it is evaluated only once.
+ AARM Discussion:
For example, the expression
- My_Array(I) := <<>>*2 + <<>>/2;
+ My_Array(I) := @*2 + @/2;
would be equivalent to
- [Target_Name] : [Target_Type] renames My_Array(I);
+ procedure [Anon] ([Target] : in out [Target_Subtype]) is
+ [Target] := [Target_Subtype]'([Target])*2 +
+ end [Anon];
- [Target_Name] := [Target_Name]*2 + [Target_Name]/2;
+ [Anon] ([Target] => My_Array(I));
+ where all of the identifiers in square brackets are anonynous
+ End AARM Discussion.
- All of the Dynamic Semantics follow directly from this equivalence.
- End AARM Discussion.
+Add after 8.6(9/4):
+ * The *variable_*name of an assignment_statement *A*, if the expression of
+ *A* contains one or more target_names.
- X := <<>> + 1; -- A short hand for X := X + 1;
+ X := @ + 1; -- A shorthand for X := X + 1;
- A(I) := Integer'Max (<<>>, 10); -- Equivalent to:
+ A(I) := Integer'Max (@, 10); -- Equivalent to:
- -- Temp : Integer renames A(I);
+ -- procedure Anon (Target : in out Integer) is
+ -- begin
+ -- Target := Integer'Max (Integer'(Target), 10);
+ -- end Anon;
- -- Temp := Integer'Max (Temp, 10);
+ -- Anon (A(I));
-<<>> is defined by equivalence to a local rename followed by an assignment
-statement; all of the static and dynamic semantics follow from this equivalence.
+The occurrence of a target_name (@) in an assignment makes the
+/variable_/name (the left-hand side of the assignment) a complete context.
+This avoids complicating resolution unnecessarily; otherwise it would be
+possible for the LHS to be overloaded in such a way that the uses of @
+determine which possibility is correct. This is especially complicated
+as @ has to resolve the same as the LHS, whereas a simple textual substitution
+would not have that property. We avoid the complication by legislating it
+This is potentially a maintenance hazard, as introducing @ into an
+assignment_statement potentially could make it illegal. However, since
+stand-alone objects and parameters cannot be overloaded, this will rarely make
+a difference in practice (there is rarely more than one interpretation of
+the LHS of an assignment).
+The expansion in terms of an anonymous procedure preserves the possibility of
+erroneous execution in obscure cases:
+ type Mutable (D : Boolean := True) is record
+ case D is
+ when True =>
+ I : Integer;
+ when False =>
+ F : Float;
+ end case;
+ end record;
+ Obj : Mutable;
+ function Fooey return Integer is
+ Temp : Integer := Obj.I;
+ Obj := (D => False, F => Float(Temp));
+ return Temp;
+ end Fooey;
+ Obj.I := @ + Fooey; -- (1)
+ Obj.I := Obj.I + Fooey; -- (2)
+In these assignments, the I component doesn't exist when it is written. Ada
+doesn't try to prevent that, both (1) and (2) are erroneous.
+We considered using a renames formulation instead:
+ Obj.I := @ + 1;
+being the same as:
+ <Target> : renames Integer := Obj.I; -- (3)
+ <Target> := <Target> + 1;
+However, this doesn't work in this case, as the renames of a discriminant
+dependent-component (like (3)) is illegal. Since the update to the I component
+is the sort of use this feature is constructed for, making it illegal seems
+too restrictive. (And this is not a new kind of erroneous execution, as
+Note that the subprogram call introduced by this formulation could introduce
+an extra possibility of a failing subtype check, but this can happen only if
+the value of the *variable_*name is invalid or a predicate has a side-effect.
+In these cases, reading the *variable_*name isn't going to be safe anyway, so
+the effect is mainly to make a latent error more visible.
+The target_name is a constant view of the LHS of the assignment. We do this
+mainly so that the use of @ does not trigger the Taft anti-aliasing rules
+(6.4.1). A side-effect is that the target object cannot be modified directly
+via @, preventing problems. We accomplish this by defining the target_name
+to expand to a qualified_expression; that expression could introduce an
+extra exception, but only if a predicate has a side-effect (the subtype
+conversion was already done by the parameter passing, this is just a repeat).
-Possible issue: Resolution of an assignment_statement is unchanged when <<>>
-is used. That means that <<>> might be overloaded if the /variable_/name is
-overloaded. That might complicate the implementation a bit; care needs to be
-taken that <<>> always is resolved with the same type. (It's possible to write
-an assignment where the text is the same on both sides of the expression
-but a different function is resolved.)
-We considered making the /variable_/name a complete context in the case that
-<<>> is used, but that potentially would be a (minor) maintenance hazard,
-as introducing <<>> might cause a perfectly good assignment to become illegal
-(if the target is overloaded).
This proposal is better than AI12-0125-2, as
- (1) No new lexical symbols are needed.
- (2) It is more flexible; it can be used in function calls other than operators
+ (1) It is more flexible; it can be used in function calls other than operators
(as shown by the 'Max example above).
- (3) It doesn't depend on visibility of anything; it's always available if the
- assignment meets the criteria of the Legality Rules.
+ (2) There is a positive indication that this notation is being used (the
+ addition of an @ as opposed to deleting an '=');
+ (3) It doesn't (directly) depend on visibility of anything; it's always
+ available unless the LHS of the assignment is overloaded.
It is different than the proposal of AI12-0125-2: (whether these are advantages
or disadvantages are in the eye of the beholder -- the author finds these to be
- (1) It doesn't have an "obvious" extension to a user-defined version, which
+ (1) Only one new lexical symbol is needed, rather than many.
+ (2) It doesn't have an "obvious" extension to a user-defined version, which
avoids a nasty slippery slope.
- (2) It doesn't look like we're out of ideas by stealing groddy parts of other
+ (3) It doesn't look like we're out of ideas by stealing groddy parts of other
+This proposal is the same as the proposal AI12-0125-2 in the following ways:
+ (1) The semantics is described in terms of an anonymous procedure.
+ (2) The left-hand side of the assignment is treated as a complete context,
+ meaning that in rare cases, introducing @ into an assignment (or using
+ :+) would make the assignment illegal.
+These should be considered issues with solving the problem as opposed to
+negatives against a particular proposal.
+ (3) Both are only one character different from very different expressions:
+ Obj:=@+1; vs. Obj:=+1; -- This proposal
+ Obj:+1; vs. Obj:=+1; -- The alternative AI12-0125-2
+Of course, writing without whitespace is discouraged in Ada, but these are
+legal expressions regardless of common practice. This problem could be
+eliminated for this proposal by using more than one character for the target
+name (as the original proposal <<>> did).
Questions? Ask the ACAA Technical Agent