Processing math: 100%

Previous Up Next

Case

A case expression has the form

case <expr0> of
	<id1> : <type1> => <expr1>;
	...
	<idn> : <typen> => <exprn>;
esac

Case expressions provide runtime type tests on objects. First, expr0 is evaluated and its dynamic type C noted (if expr0 evaluates to void a run-time error is produced). Next, from among the branches the branch with the least type <typek> such that C≤<typek> is selected. The identifier <idk> is bound to the value of <expr0> and the expression <exprk> is evaluated. The result of the case is the value of <exprk>. If no branch can be selected for evaluation, a run-time error is generated. Every case expression must have at least one branch.

For each branch, let Ti be the static type of <expri>. The static type of a case expression is 1inTi. The identifier id introduced by a branch of a case hides any variable or attribute definition for id visible in the containing scope.

The case expression has no special construct for a "default" or "otherwise" branch. The same affect is achieved by including a branch

x : Object => ...

because every type is to Object.

The case expression provides programmers a way to insert explicit runtime type checks in situations where static types inferred by the type checker are too conservative. A typical situation is that a programmer writes an expression e and type checking infers that e has static type P. However, the programmer may know that, in fact, the dynamic type of e is always C for some CP. This information can be captured using a case expression:

case e of x : C => ...

In the branch the variable x is bound to the value of e but has the more specific static type C.

Previous Up Next