Version 1.3 of ai12s/ai12-0053-1.txt

Unformatted version of ai12s/ai12-0053-1.txt version 1.3
Other versions for file ai12s/ai12-0053-1.txt

!standard 3.2.4(31/3)          12-12-27 AI12-0053-1/02
!standard 4.6(57/3)
!class binding interpretation 12-12-08
!status No Action 10-0-1 12-12-08
!status work item 12-12-08
!status received 12-12-07
!priority High
!difficulty Medium
!qualifier Error
!subject Predicate failure raises Constraint_Error
!summary
Predicate failure raises Constraint_Error, not Assertion_Error.
!question
Should predicates raise Constraint_Error on failure? (Yes.)
!recommendation
See !summary.
!wording
3.2.4(31/3):
31/3 ... {Constraint_Error}[Assertions.Assertion_Error] is raised if any of
these checks fail.
4.6(57/3):
57/3 If an Accessibility_Check fails, Program_Error is raised. If a predicate check fails, {Constraint_Error}[Assertions.Assertion_Error] is raised. Any other check associated with a conversion raises Constraint_Error if it fails.
!discussion
Predicates need to be interchangeable with constraints, so one can switch back and forth between them. Therefore, predicates need to raise Constraint_Error on failure. Having them raise Assertion_Error was a mistake.
As an example, see AI12-0037-1. The Ada.Locales package was originally designed to have these types:
type Language_Code is array (1 .. 3) of Character range 'a' .. 'z'; type Country_Code is array (1 .. 2) of Character range 'A' .. 'Z';
However, it was discovered that these types are not convertible to/from String, which makes it rather inconvenient to do text IO. Therefore, AI12-0037-1 changed the types to use predicates:
type Language_Code is new String(1 .. 3) with Dynamic_Predicate => (for all E of Language_Code => (E in 'a' .. 'z')); type Country_Code is new String(1 .. 2) with Dynamic_Predicate => (for all E of Country_Code => (E in 'A' .. 'Z'));
Another case comes up when enumeration literals are added to an existing type. For instance, imagine that a program contains the following declarations:
type Enum is (A, B, C, D); subtype Sub is Enum range A .. C;
Now, we discover that we need to add a new literal in the middle of the enumeration, but that Sub should not include that literal. We can use a static predicate to keep the semantics of Sub the same:
type Enum is (A, B, E, C, D); subtype Sub is Enum with Static_Predicate => Sub in A | B | C;
In order to preserve compatibility, it is important that these kinds of changes be possible without changing the exception that is raised on failure.
!appendix

This AI was created out of discussion on AI12-0037-1 during ARG meeting
#48 in Boston.

****************************************************************

Questions? Ask the ACAA Technical Agent