CVS difference for ai12s/ai12-0022-1.txt

Differences between 1.3 and version 1.4
Log of other versions for file ai12s/ai12-0022-1.txt

--- ai12s/ai12-0022-1.txt	2012/05/19 02:42:48	1.3
+++ ai12s/ai12-0022-1.txt	2012/06/29 04:05:15	1.4
@@ -1,9 +1,12 @@
-!standard 11.3(2/2)                                      12-05-11    AI12-0022-1/02
+!standard 4.4(3/3)                                12-06-28    AI12-0022-1/03
+!standard 11.2(6)
+!standard 11.3(2/2)
 !standard 11.3(3)
 !standard 11.3(3.1/2)
 !standard 11.3(4/2)
 !standard 11.4.1(10.1/3)
 !class Amendment 12-03-16
+!status ARG Approved 9-0-0  12-06-1
 !status work item 12-02-24
 !status received 12-02-24
 !priority High
@@ -26,34 +29,31 @@
 
 !wording
 
-Add to 4.4(7/3):
+Add to 4.4(3/3):
 
-    ... | (raise_expression)
+    | raise_expression
 
-Rename 11.3 to "Raise Statements and Expressions"
+Rename 11.3 to "Raise Statements and Raise Expressions"
 
-After 11.3(2/2) [Syntax]
+Add before 11.2(6):
 
-raise_expression ::= raise exception_name [with string_expression]
+An *exception*_name of an exception_choice shall denote an exception.
 
-Wherever the Syntax Rules allow an expression, a raise_expression may be used in place of the expression,
-so long as it is immediately surrounded by parentheses.
+Add after 11.3(2/2) [Syntax]
 
-AARM Note: The syntactic category raise_expression appears only as a primary that is parenthesized. The
-above rule allows it to additionally be used in other contexts where it would be directly surrounded by
-parentheses. This is the same rule that is used for conditional_expressions; see 4.5.7 for a detailed
-discussion of the meaning and effects of this rule. 
+raise_expression ::= raise *exception*_name [with *string*_expression]
 
 Modify 11.3(3): [Legality Rules]
 
-The name, if any, in a raise_statement {or raise_expression} shall denote an exception. A
+{An exception_name of}[The name, if any, in] a raise_statement {or
+raise_expression} shall denote an exception. A
 raise_statement with no exception_name (that is, a re-raise statement) shall be within a
-handler, but not within a body enclosed by that handler. 
+handler, but not within a body enclosed by that handler.
 
 Modify 11.3(3.1/2): [Name Resolution Rules]
 
-The expression, if any, in a raise_statement {or raise_expression}, is expected to be
-of type String. 
+{A *string*_expression of}[The expression, if any, in] a raise_statement
+{or raise_expression}[,] is expected to be of type String.
 
 Add after 11.3(3.1/2):
 
@@ -71,11 +71,11 @@
 
 Modify 11.4.1(10.1/3):
 
-... For the occurrence raised by a {raise_expression or} raise_statement with an exception_name
-and a string_expression, the message is the string_expression. For the occurrence raised by a 
-{raise_expression or} raise_statement with an exception_name but without a string_expression,
-the message is a string giving implementation-defined information about the exception occurrence.
-...
+... For the occurrence raised by a raise_statement {or raise_expression} with an
+exception_name and a string_expression, the message is the string_expression.
+For the occurrence raised by a raise_statement {or raise_expression} with an
+exception_name but without a string_expression, the message is a string giving
+implementation-defined information about the exception occurrence. ...
 
 !discussion
 
@@ -90,30 +90,52 @@
 
 ---
 
-A raise_expression resolves to "any type". That means it might be necessary to qualify it
-in some circumstances, but the need for that should be rare.
+A raise_expression has the precedence of a relation. This means that it will
+need to be parenthesized in most contexts. But it will not need to be
+parenthesized when used directly in a context like a conditional expression
+or return statement. It also will not need to be parenthesized when used
+directly with a logical operator/operation (and, and then, etc.).
+
+For instance:
+    (if Mode /= In_File then raise Mode_Error)
+is preferable to:
+    (if Mode /= In_File then (raise Mode_Error))
+
+We can't allow a raise_expression to go unparenthesized in all contexts,
+as there is an ambiguity with the optional string_expression. Does
+    raise Some_Error with "aaa" & "bbb"
+mean
+    (raise Some_Error with "aaa") & "bbb"
+or
+    (raise Some_Error with "aaa" & "bbb")
 
-It was suggested that the type be "any Boolean type", but that limits the usefulness of
-the construct in conditional expressions. For instance, imagine the following expression
-function:
+We avoid this situation by using precedence so that the raise_expression
+has to be surrounded by parentheses if used with the "&" operator.
 
+---
+
+A raise_expression resolves to "any type". That means it might be necessary to
+qualify it in some circumstances, but the need for that should be rare.
+
+It was suggested that the type be "any Boolean type", but that limits the
+usefulness of the construct in conditional expressions. For instance, imagine
+the following expression function:
+
     function Foo (Bar : in Natural) return Natural is
         (case Bar is
             when 1 => 10,
             when 2 => 20,
             when others => (raise Program_Error)));
 
-This is allowed as a raise_expression resolves to "any type"; it it resolved to
+This is allowed as a raise_expression resolves to "any type"; if it resolved to
 "any Boolean type", some junk expression like "and True" would have to appended to
 make it legal -- which would do nothing for readability or understandability.
 
----
+In addition, resolving to "amy type" also solves the problem posed in
+AI12-0029-1, as that means "return raise Not_Implemented_Error;" is legal
+for any function. This makes it an easy idiom to use for functions that
+(temporarily) always raise an exception.
 
-We used the same parenthesization rules as for conditional_expressions and other complex
-expression components. We probably don't need the parens to avoid ambiguity as we
-do in some of the other cases, but it seems valuable to have consistency in how these
-"statements as part of an expression" are presented.
-  
 ---
 
 Example: Imagine the following routine in a GUI library:
@@ -127,7 +149,7 @@
 
     subtype Valid_Root_Window is Root_Window
        with Dynamic_Predicate =>
-           Is_Valid (Valid_Root_Window) or else (raise Not_Valid_Error);
+           Is_Valid (Valid_Root_Window) or else raise Not_Valid_Error;
 
     procedure Show_Window (Window : in out Valid_Root_Window);
        -- Shows the window.
@@ -136,12 +158,18 @@
 change the exception raised on this failure. That could cause the exception
 to fall into a different handler than currently, which is likely to not be
 acceptable.
+
+An alternative way to write the predicate might be preferable:
+
+    subtype Valid_Root_Window is Root_Window
+       with Dynamic_Predicate =>
+           (if not Is_Valid (Valid_Root_Window) then raise Not_Valid_Error);
 
-Similarly, the various Containers packages in Ada could use predicates in
-this way to make some of the needed checks; but that can only be done if the
-semantics remains unchanged (raising Program_Error and Constraint_Error,
-not Assertion_Error). (The !proposal also shows how this could be used in
-Text_IO and other I/O packages.)
+Similarly, the various Containers packages in Ada could use predicates or
+preconditions in this way to make some of the needed checks; but that can only
+be done if the semantics remains unchanged (raising Program_Error and
+Constraint_Error, not Assertion_Error). (The !proposal also shows how this could
+be used in Text_IO and other I/O packages.)
 
 ---
 
@@ -166,9 +194,9 @@
 subprogram may include multiple exceptions that need to be checked:
 
      procedure Put (File : in File_Type; Str : in String)
-        with Pre => (Is_Open(File) or else (raise Status_Error)) and then
+        with Pre => (Is_Open(File) or else raise Status_Error) and then
                     (Mode(File) = Out_File or else
-                     (raise Mode_Error with "Cannot read " & Name(File)));
+                     raise Mode_Error with "Cannot read " & Name(File));
 
 This cannot be handled with a single exception clause or aspect. This particular
 problem could be addressed by making the Status_Error check into a predicate, but
@@ -181,17 +209,19 @@
         with Pre => Is_Open(File), Pre_Exception => Status_Error,
              Pre => Mode(File) = Out_File, Pre_Exception => Mode_Error;
 
-but notice that the order of declaration of the preconditions is significant here, which
-is likely to be confusing (and a significant change from the current rules, where the
-order of evaluation of preconditions is unspecified).
-
-In addition, we've lost the exception message that gives the name of the file with
-the wrong mode. That's a loss; we could introduce another aspect to deal with that,
-but by now it's clear that this solution is not "simpler" by any stretch of imagination.
-
-The problem with the last alternative is the need to clutter the program with a number of
-exception raising functions. This is especially problematic in existing packages (like the
-language-defined ones) where adding these routines is not allowed.
+but notice that the order of declaration of the preconditions is significant
+here, which is likely to be confusing (and a significant change from the current
+rules, where the order of evaluation of preconditions is unspecified).
+
+In addition, we've lost the exception message that gives the name of the file
+with the wrong mode. That's a loss; we could introduce another aspect to deal
+with that, but by now it's clear that this solution is not "simpler" by any
+stretch of imagination.
+
+The problem with the last alternative is the need to clutter the program with a
+number of exception raising functions. This is especially problematic in
+existing packages (like the language-defined ones) where adding these routines
+may not be allowed.
 
 Thus the selected alternative seems clearly to be the best option.
 

Questions? Ask the ACAA Technical Agent