CVS difference for ai12s/ai12-0054-1.txt
--- ai12s/ai12-0054-1.txt 2012/12/29 03:53:24 1.2
+++ ai12s/ai12-0054-1.txt 2013/01/31 05:03:54 1.3
@@ -1,4 +1,4 @@
-!standard 11.3(4/2) 12-12-09 AI12-0054-1/02
+!standard 11.3(4/2) 13-01-24 AI12-0054-1/03
!class binding interpretation
@@ -49,13 +49,14 @@
Add a new paragraph after that:
There is one exception to the above rule: For an individual membership test (see
-4.5.2) of the form "X in S", where S has a predicate that contains a
-raise_expression, if that raise_expression is evaluated, then the exception is
-not raised; instead, the entire predicate immediately evaluates to False. This
-includes raise_expressions contained within the default_expression for a formal
-parameter, but not raise_expressions within the default_expression for a
+4.5.2) of the form "X in S", if a raise_expression within the predicate of S is
+evaluated, then the exception is not raised; instead, the entire predicate
+immediately evaluates to False. This includes raise_expressions within the
+default_expression for a formal parameter.
+AARM Discussion: But it does NOT include raise_expressions within the
+default_expression for a component; those actually raise the exception.
Modify 13.9.2(2-3/3) so it refers to the semantics of "in" rather than directly to the semantics of the predicate, so the newly-modified semantics of "in"
automatically work for 'Valid:
@@ -71,9 +72,9 @@
-Note that "contains" in the new wording means statically/textual containment.
-We're not talking about anything dynamic. But we do include formal parameter
+Note that "within" in the new wording means statically/textual containment as
+usual. We're not talking about anything dynamic. But we do include formal
The purpose of a raise_expression in an assertion is to specify which exception
is raised on failure. For example:
@@ -102,12 +103,15 @@
we don't want to raise Program_Error. We want the 'if' condition to return True
or False according to whether Is_Round(X) is True. Therefore, we change the rule
so that "Is_Round(S) or else raise Program_Error" is evaluated as "Is_Round(S)
-or else False" -- but only for membership tests.
+or else predicate-is-False" -- but only for membership tests.
Note that this special case for raise_expressions in membership tests does not
apply to any other ways of raising an exception. For example, if Is_Round(X)
propagates an exception, then the membership test propagates that exception
+occurrence. This unfortunately means you cannot in general make use of
+abstraction by moving an (entire) existing predicate into a function body (or
+expression function); to make that transformation you need to leave the "raise"
The following example shows how to raise a particular exception for a particular
"reason" the predicate fails. If the evaluation of "X in T" evaluates one of the
@@ -121,11 +125,13 @@
Rationale for the default_expression business: A defaulted parameter really
should be strongly equivalent to an explicit parameter. Switching from one to
-the other should not cause subtle changes in run-time semantics. The component
-case is less clear, but there would be an implementation difficulty if we made
-the opposite choice, for implementations that choose to wrap default
-initializations in an initialization procedure (whether or not inlined), because
-an extra "we're in an 'in'" flag would need to be passed.
+the other should not cause subtle changes in run-time semantics.
+The component case is less clear. We choose to treat those in the opposite way
+(the exception is raised) because otherwise there would be an implementation
+difficulty for implementations that choose to wrap default initializations in an
+initialization procedure (whether or not inlined), because an extra "we're in an
+'in'" flag would need to be passed.
Intended implementation: If the implementation chooses to generate code for
predicates inline at the places where they are used, then it would be
@@ -133,7 +139,9 @@
predicate" whenever the predicate is being evaluated as part of a membership
test. If an implementation uses an out-of-line function to evaluate the
predicate, it can pass an extra "In_Membership" flag, or it can generate two
-copies of the function.
+copies of the function. Either way, the raise isn't replaced by False -- it is
+replaced by a jump to a place that returns False for the whole predicate. The
+above type T with mixed "and then" and "or else" shows why.
An implementation that wraps the predicate with an exception handler like "when
others => False" would be incorrect. An implementation that turns "raise ..."
Questions? Ask the ACAA Technical Agent