John Barnes

3.3 Case expressions

Case expressions have much in common with if expressions and the two are collectively known as conditional expressions.
Thus given a variable D of the familiar type Day, we can assign the number of hours in a working day by
Hours := (case D is
when Mon .. Thurs => 8,
when Fri => 6,
when Sat | Sun => 0);
A slightly more adventurous example involving nested if expressions is
Days := (case M is
when September | April | June | November => 30,
when February =>
(if Year mod 100 = 0 then
(if Year mod 400 =0 then 29 else 28)
else
(if Year mod 4 = 0 then 29 else 28)),
when others => 31);
The reader is invited to improve this!
Note the similarity to the rules for if expressions. There is no closing end case. Case expressions are always enclosed in parentheses but they can be omitted if the context already provides parentheses.
If M and Year are static then the case expression as a whole is also static. If M is static and equal to September, April, June or November then the value is statically known to be 30 so that the expression for February is statically unevaluated even if Year is not static. Note that the various choices are evaluated in order.
The rules regarding the types of the dependent expressions are exactly as for if expressions. Thus if the case expression is the argument of a type conversion then the conversion is effectively pushed down to the dependent expressions.
It is always worth emphasizing that an important advantage of case constructions is that they give a coverage check. Thus in the previous chapter we had
subtype Pet is Animal
with Static_Predicate =>
(case Pet is
when Cat | Dog | Horse => True,
when Bear | Wolf => False);
which is much more reliable than
subtype Pet is Animal
with Static_Predicate => Pet in Cat | Dog | Horse;
because when we add Rabbit to the type Animal, we are forced to include it in one branch of the case expression whereas it is all too easy to forget it using an if expression.

© 2011, 2012, 2013 John Barnes Informatics.