CVS difference for ai12s/ai12-0342-1.txt
--- ai12s/ai12-0342-1.txt 2019/11/09 01:33:32 1.3
+++ ai12s/ai12-0342-1.txt 2020/01/11 05:13:40 1.4
@@ -1,4 +1,4 @@
-!standard 4.2.1(0) 19-09-24 AI12-0342-1/01
+!standard 4.2.1(0) 20-01-10 AI12-0342-1/02
!standard 6.3.1(22)
!reference AI12-0249-1
!reference AI12-0295-1
@@ -13,16 +13,12 @@
!summary
The aspects related to user-defined literals are inheritable.
-In order to make inheritance work in the tagged case, we follow
-the example of the Constant_Indexing and Variable_Indexing aspects:
-the literal-related aspects specify the name of a subprogram,
-as opposed to specifying a subprogram.
-
-A user-defined literal was previously defined to be have the same
-dynamic semantics as a function call. That equivalence is extended
-to also apply in a number of cases involving static semantics
-(e.g., interactions with abstract types and abstract subprograms).
+The "a literal is equivalent to a call" equivalence is
+extended from just dynamic semantics into static semantics.
+
+Conformance rules are tightened up for user-defined literals.
+
!problem
There are a number of issues with definition of user-defined literals
@@ -31,178 +27,111 @@
!proposal
-(See summary.)
-
-!wording
+This AI is about two topics:
+ 1) Inheritance of Integer_Literal, Real_Literal, and String_Literal
+ aspects. These aspects are inherited according to the rules given
+ in 13.1. In the case of type extension, any such inherited aspects
+ must be overridden.
+ 2) Treating a user-defined literal like a function call for purposes
+ static semantics, not just dynamic semantics. This is intended to
+ clarify, for example, the rules about how user-defined literals interact
+ with abstract types and abstract subprograms.
-Replace all of 4.2.1 with the following:
+A minor hole in the 6.3.1 conformance rules is also addressed.
-4.2.1 User-Defined Literals
+!wording
-Using one or more of the aspects defined below, a type may be specified to
-allow the use of one or more kinds of literals as values of the type.
+In 4.2.1(2/5), delete "nonoverridable, ".
-Static Semantics
+In 4.2.1(3/5, 4/5, and 5/5), replace (once in each)
+ "primitive function of T" with "function"
-The following nonoverridable, type-related operational aspects may be
-specified for any type T:
-
-Integer_Literal
-
- This aspect is specified by a direct_name that denotes a
- primitive function of T with one parameter of type String
- and a result type of T.
-
-Aspect Description for Integer_Literal:
- Specifies the name of a function to be used to implement user-defined
- integer literals.
-
-Real_Literal
-
- This aspect is specified by a direct_name that denotes a
- primitive function of T with one parameter of type String
- and a result type of T.
-
-Aspect Description for Real_Literal:
- Specifies the name of a function to be used to implement user-defined
- real literals.
-
-String_Literal
-
- This aspect is specified by a direct_name that denotes a
- primitive function of T with one parameter of type Wide_Wide_String
- and a result type of T.
-
-[TBD: the corresponding uses of function_name instead of direct_name
-in 4.1.6 probably should be changed to match the above; we don't want to allow
- package Foo is
- ...
- type T is ... with Constant_Indexing => Foo.Bar;
- function Bar ... ;
- ...
- end Foo;
-, right?]
-
-Aspect Description for String_Literal:
- Defines a function to implement user-defined string literals.
-
-The preceding three rules about what the direct_name
-in an aspect specification shall denote are name resolution rules.
-[AARM note:
-Thus, the following example is legal:
- package P is
- type T is record X, Y : Integer; end record
- with Integer_Literal => Int_Lit;
- function Int_Lit (X, Y : T) return Duration; -- wrong profile
- function Int_Lit (Lit_Image : String) return T; -- right profile
- end;
-]
-
-When a numeric literal is interpreted as value of a non-numeric
-type T or a string_literal is interpreted a value of a type T that
-is not a string type (see 4.2), it is equivalent to a call to the primitive
-operation of type T denoted by the corresponding aspect of T: the
-Integer_Literal aspect for an integer literal, the Real_Literal aspect
-for a real literal, and the String_Literal aspect for a string_literal.
-Such a literal is said to be a "user-defined literal".
-
-[TBD: We could define the term "user-defined literal" in 4.2 instead.]
-
-[AARM note: Many properties are determined by this equivalence.
-For example, the result of evaluating such a literal is an object
-because the return object of a function is an object. The
-nominal type, nominal subtype, and accessibility level are defined
-as for the equivalent function call. Such a literal is considered
-to be statically tagged, dynamically tagged, or tag indeterminate depending
-on the status of the equivalent function call. The freezing associated with
-evaluation of a user-defined literal is the freezing associated with the
-equivalent function call. This list of properties is not intended to be
-exhaustive.]
-
-These aspects are inherited by specific descendants of T.
-[AARM note: These aspects are never specified for or inherited by
-a class-wide type.]
-
-Legality Rules
-
-The Integer_Literal or Real_Literal aspect shall not be specified for a
-type T if the full view of T is a numeric type. The String_Literal aspect
-shall not be specified for a type T if the full view of T is a string type.
-
-A user-defined literal is illegal if the equivalent function call is illegal.
-
-[AARM note: For example, this implies that if the equivalent function call
-is a call to an abstract subprogram then the equivalent function call
-shall be a dispatching call.]
-
-A user-defined integer literal of a type T is illegal if the type T
-does not have exactly one visible primitive function having the name
-specified in T's (explicit or inherited) Integer_Literal aspect specification,
-a result type of T, one parameter of type String, and no other parameters.
-[AARM note: If exactly one such primitive function exists then that is the
-function that is called when the literal is evaluated.]
-
-A user-defined real literal of a type T is illegal if the type T
-does not have exactly one visible primitive function having the name
-specified in T's (explicit or inherited) Real_Literal aspect specification,
-a result type of T, one parameter of type String, and no other parameters.
-[AARM note: If exactly one such primitive function exists then that is the
-function that is called when the literal is evaluated.]
-
-A user-defined string literal of a type T is illegal if the type T
-does not have exactly one visible primitive function having the name
-specified in T's (explicit or inherited) String_Literal aspect specification,
-a result type of T, one parameter of type Wide_Wide_String, and no other
-parameters.
-[AARM note: If exactly one such primitive function exists then that is the
-function that is called when the literal is evaluated.]
-
-[AARM note: This implies that the following examples are illegal:
- package Too_Few is
- type T1 is null record with Integer_Literal => I_L;
- type T2 is new T1;
- function I_L (S : String) return T1 is (null record);
- X : T2 := 123; -- too few candidates
- end Too_Few;
+Append after 4.2.1 (5.a/5) (i.e., at the end of the Static Semantics section)
- procedure Too_Many is
- generic
- type Element is private;
- package G is
- type T is (Aa, Bb, Cc) with Integer_Literal => I_L;
- function I_L (X : String) return T1;
- function I_L (X : Element) return T1;
- end G;
- package body G is ... end;
- package I is new G (Element => String);
- X : I.T := 123; -- too many candidates
- begin null; end;
-]
+ [AARM note:
+ Thus, the following example is legal because the preceding rules
+ are name resolution rules (see 13.1.1):
+ package Pkg1 is
+ type T is record X, Y : Integer; end record
+ with Integer_Literal => Int_Lit;
+ function Int_Lit (X, Y : T) return Duration; -- wrong profile
+ function Int_Lit (Lit_Image : String) return T; -- right profile
+ end;
+ end AARM note]
+
+ These three aspects are inherited according to the rules given in 13.1.
+
+ [AARM Note:
+ This means that in this example
+ package Pkg is
+ type T1 is record
+ X, Y : Integer;
+ end record with Integer_Literal => I_L;
+
+ function I_L (S : String) return T1 is ((0, 0));
+
+ type T2 is new T1;
+ function I_L (S : String) return T2 is ((1, 1));
+ X : T2 := 123;
+ end Pkg;
+
+ the initial value of Pkg.X is (0,0), not (1,1).
+ end AARM note]
+
+ When a numeric literal is interpreted as value of a non-numeric
+ type T or a string_literal is interpreted a value of a type T that
+ is not a string type (see 4.2), it is equivalent to a call to the
+ subprogram denoted by the corresponding aspect of T: the
+ Integer_Literal aspect for an integer literal, the Real_Literal aspect
+ for a real literal, and the String_Literal aspect for a string_literal.
+ The actual parameter of this notional call is a string literal
+ having the textual representation of the original (numeric or
+ string) literal.
+
+ Such a literal is said to be a "user-defined literal".
+
+ [AARM note:
+ This equivalence defines, for example, the nominal type, the nominal
+ subtype, and the accessibility level of a user-defined literal.
+ It also has the consequence that a user-defined literal shall not
+ be of an abstract type (because that would be equivalent to a
+ nondispatching call to an abstract function). This equivalence
+ also defines the dynamic semantics of evaluating a user-defined
+ literal.]
+
+Append after 4.2.1(6/5) (i.e., at the end of the Legality Rules section)
+
+ If a nonabstract tagged type inherits any of these three aspects,
+ then each inherited aspect shall be overridden.
+
+Replace 6.3.1(22-22.a)
+ - each primary that is a literal in one has the same value as the
+ corresponding literal in the other.
-In addition to the places where Legality Rules normally apply (see 12.3),
-these rules also apply in the private part of an instance of a generic unit.
+ Ramification: The literals may be written differently.
-Dynamic Semantics
+with
+ - each primary that is a literal in one is a user-defined literal
+ if and only if the corresponding literal in the other is also a
+ user-defined literal. Furthermore, if neither are user-defined literals
+ then they shall have the same values [redundant , but they may have
+ differing textual representations]; if both are user-defined literals then
+ they shall have the same textual representation.
-For the evaluation of a user-defined literal, the result is the
-result of the equivalent function call described above. The actual
-parameter that is passed in is as follows:
- - For a numeric literal, the String with lower bound one whose value
- corresponds to the textual representation of the literal;
- - For a string_literal, the Wide_Wide_String with lower bound one
- that corresponds to the literal.
+delete the entire Dynamic Semantics section (it is now redundant)
-[AARM note: Within an expanded instance of a generic unit, the usual
-rules about resolution of primitives of formal derived types apply.
+!discussion
-That means that in this example,
+Because these are aspects, we don't get reemergence for with
+formal derived types (the way that we might with primitive
+subprograms). That means that in this example,
procedure Proc is
package Pkg is
- type T1 is (T1_Op, T2_Op) with Integer_Literal => I_L;
- function I_L (S : String) return T1 is (T1_Op);
+ type T1 is (T1_Op, T2_Op) with Integer_Literal => F1;
+ function F1 (S : String) return T1 is (T1_Op);
- type T2 is new T1;
- function I_L (S : String) return T2 is (T2_Op);
+ type T2 is new T1 with Integer_Literal => F2;
+ function F2 (S : String) return T2 is (T2_Op);
end Pkg;
generic
@@ -216,128 +145,8 @@
package I is new G (T2);
begin null; end;
-
-the variable I.X is initialized with the value T1_Op, not T2_Op.]
-
----
-
-Replace 6.3.1(22-22.a)
- - each primary that is a literal in one has the same value as the
- corresponding literal in the other.
-
- Ramification: The literals may be written differently.
-
-with
- - each primary that is a literal in one is a user-defined literal
- if and only if the corresponding literal in the other is also a
- user-defined literal. Furthermore, if neither are user-defined literals
- then they shall have the same values [redundant , but they may have
- differing textual representations]; if both are user-defined literals then
- they shall have the same textual representation.
-
-!discussion
-
-This AI is about two topics:
- 1) Inheritance of Integer_Literal, Real_Literal, and String_Literal
- aspects.
- 2) Treating a user-defined literal like a function call for purposes
- static semantics, not just dynamic semantics. This is intended to
- clarify, for example, the rules about how user-defined literals interact
- with abstract types and abstract subprograms.
-
-A minor hole in the 6.3.1 conformance rules is also addressed.
-
-1) Inheritance
-
-As the RM stands today, the Integer_Literal, Real_Literal, and String_Literal
-aspects are not inherited. This was clearly unintended and needs to be fixed.
-Background:
- The Integer_Literal, Real_Literal, and String_Literal aspects are
- defined to be operational aspects.
-
- 13.1 says
- ... whether operational aspects are inherited by a derived type
- depends on each specific aspect; unless specified, an operational
- aspect is not inherited.
-
- There is currently no mention of inheritance or of derived types in 4.2.1
- (the section on User-Defined Literals), so the aspects are not inherited.
-
-Simply saying "ok, so those aspects are inherited" isn't enough. In
-a tagged case like
- type T1 is tagged record ... end record
- with Integer_Literal => Nested_Pkg.Nonprimitive_Function;
- package Nested_Pkg is
- function Nonprimitive_Function (Lit_Image : String) return T1;
- end Nested_Pkg;
- type T2 is new T1 with record ... <more components> ... end record;
-the "default" inheritance rule described in 13.1(15.2/2) doesn't work.
-
-To address this issue, we follow the model of the Constant_Indexing
-and Variable_Indexing aspects; the value of these aspects is not a
-subprogram but rather the name of a subprogram. [Although unlike those two
-aspects, the specified name denotes exactly one primitive subprogram of the
-type.] This means that,
-even though the three aspects are nonoverridable, users can get the
-effect of overriding by overriding the primitive operation named by
-the aspect value.
-
-In this example,
-
- package Pkg is
- type T1 is record X, Y : Integer; end record with Integer_Literal => I_L;
- function I_L (S : String) return T1 is ((0, 0));
- type T2 is new T1;
- function I_L (S : String) return T2 is ((1, 1));
- X : T2 := 123; --
- end;
-
-the initial value of Pkg.X is (1,1), not (0,0).
-
-2) Extending "function call" equivalence rule into static semantics.
-
-Currently, the equivalence between a user-defined literal and a
-call to the specified function is defined only as a dynamic semantics
-rule. This results in a lot of definitional holes that are addressed
-by extending the application of this equivalence into static semantics.
-
-For example, assume we have a tagged type Big_Num whose Integer_Literal
-aspect specifies a primitive operation of the type, and which also
-has a primitive two-parameter addition operator with the usual profile.
-Suppose further that we have this procedure:
-
- procedure Increment (X : in out Big_Num'Class) is
- begin
- X := X + 1;
- end;
-
-We want this example to be legal, but that requires a rule that
-somehow causes the literal to be treated as a tag-indeterminant call.
-The second topic of this AI is issues of this kind.
-
-I have discussed earlier versions of this proposal with Randy and Tuck.
-
-They feel (I hope I am stating their position correctly) that following
-the "Constant_Indexing model", where the value of the aspect is not a
-subprogram but rather the name of a subprogram, may be unnecessarily complex
-in the case where the aspect refers to a single subprogram rather than
-to (potentially) a set of subprograms (as is the case with the
-Constant_Indexing aspect). They would prefer something more similar
-to the way that inheritance of streaming attributes is handled. This would
-presumably involve mandatory overriding in the case of a type extension.
-
-Tuck makes the good point that we need to agree on a meta-rule to decide
-when to use which model so that we don't end up making this decision
-arbitrarily on an aspect-by-aspect basis as new aspects arise.
-
-We should discuss this issue, but today's proposal follows the
-Constant_Indexing model. I am not sure that this is the best approach, but
-it does solve the inheritance problems associated with type extensions.
-
-Randy questions whether these new aspects need to be overridable. I think
-we at least want the property (which is a consequence of being overridable)
-that all views of a single type agree with respect to the new aspects.
+the variable I.X is initialized with the value T2_Op, not T1_Op.]
!ASIS
Questions? Ask the ACAA Technical Agent