Version 1.2 of ai05s/ai05-0188-1.txt
!standard 4.5.7 (0) 10-01-07 AI05-0188-1/02
!class amendment 09-11-03
!status work item 09-11-03
!status received 09-11-03
!priority Low
!difficulty Medium
!subject Case expressions
!summary
case expressions are added to Ada.
!problem
Conditional_expressions are added by AI05-0147-1. This proposal is to add an
analogous contruct -- the case expression.
The full coverage rules for case statements and aggregates are a huge benefit to
maintenance of Ada programs: If you add an enumeration literal, the compiler
tells you about all the case statements and aggregates that need to be modified
(assuming you don't defeat the full coverage rules by using "others").
In cases where conditional_expressions are useful, we don't want to lose the
benefits of full coverage rules. A common example is in preconditions. Suppose
we have:
procedure Add_To_Fruit_Salad( --
Fruit : in out Fruit_Type; Bowl : in out Bowl_Type);
procedure Add_To_Fruit_Salad( --
Fruit : in out Fruit_Type; Bowl : in out Bowl_Type) is
begin
--
case Fruit.Kind is
when Apple =>
pragma Assert(Fruit.Is_Crisp);
null;
when Banana =>
pragma Assert(Fruit.Is_Peeled);
null;
when Pineapple =>
pragma Assert(Fruit.Is_Cored);
null;
end case;
Cut_Up(Fruit);
Add_To_Bowl(Fruit, Bowl);
end Add_To_Fruit_Salad;
We would like to remove those assertions, and make them into preconditions:
procedure Add_To_Fruit_Salad(
Fruit : in out Fruit_Type; Bowl : in out Bowl_Type)
with
Pre =>
(if Fruit.Kind = Apple then Fruit.Is_Crisp
elsif Fruit.Kind = Banana then Fruit.Is_Peeled
elsif Fruit.Kind = Pineapple then Fruit.Is_Cored);
But then if we add Orange to the Fruit_Kind type, we might be missing a
precondition. It would be better to write it like this:
procedure Add_To_Fruit_Salad(
Fruit : in out Fruit_Type; Bowl : in out Bowl_Type)
with
Pre =>
(case Fruit.Kind is
when Apple => Fruit.Is_Crisp,
when Banana => Fruit.Is_Peeled,
when Pineapple => Fruit.Is_Cored);
Now if we add Orange, we will get an error, prompting us to add "when Orange =>
Fruit.Is_Juicy", or "when Orange => True", or whatever is appropriate.
Without case expressions, we are left with a nasty choice: put the assertions in
the body, where they don't belong, or lose the full coverage rules.
!proposal
(See wording.)
!wording
In 4.4(7), add:
primary ::=
numeric_literal | null | string_literal | aggregate | name |
allocator | (expression) | conditional_expression
Add a new clause:
4.5.7 Conditional expressions
Syntax
case_expression ::=
(case expression is
case_expression_alternative {,
case_expression_alternative}
)
case_expression_alternative ::=
when discrete_choice_list =>
expression
???I don't have time to write up all the rules right now.
Let's first see if this idea will fly at all.
Basically, the rules can be patterned after the rules for case statements,
especially the full coverage rules. "when others" is allowed, and as for case
statements, should be used with discretion.
We also want to add it to qualified_expression, as for conditional_expression:
qualified_expression ::=
subtype_mark'(expression) | subtype_mark'aggregate |
subtype_mark'conditional_expression
subtype_mark'case_expression
There is nothing corresponding to the implicit "else False" for
conditional_expressions.
We need rules for static expressions. There are two parts. One is left for
later.
The other part is based on the changes proposed in AI05-0147-1. We need to add
an additional bullet to the definition of "statically unevaluated":
* an expression of a case expression alternative where the expression of
the enclosing case expression is static and has a value that is
not covered by the discrete_choice_list of the case expression alternative.
!discussion
!examples
!ACATS test
ACATS B and C tests are needed.
!appendix
From: Bob Duff
Sent: Tuesday, November 3, 2009 1:10 PM
Here's an AI on case expressions, to complement conditional expressions.
[This is version /01 of the AI - ED]
****************************************************************
From: Robert Dewar
Sent: Tuesday, November 3, 2009 1:19 PM
> Case expressions are added to Ada.
looks good to me, I am going to go ahead and implement this in GNAT
****************************************************************
Questions? Ask the ACAA Technical Agent