CanExpression ::= Expression CAN Identifier
The CAN operator takes an expression and an identifier, and returns TRUE if the expression supports a feature or an annotation, denoted by the identifier.
The CAN operator can be used to extend polymorphism beyond what inheritance provides. For instance, in COBOL, many but not all statements can be closed by an optional END keyword. In all the classes that describe COBOL statement, the test of the presence of this optional END keyword is implemented by a feature named End.
If we would like to ensure that all statements that do support the presence of the optional END keyword, the following script will fail:
ON Statement DO
IF NOT X.End THEN
OUT.WriteLn ("Non-closed statement");
END;
END;
because the End feature is not available to all statements. The right script to write is:
ON Statement DO
IF (X CAN End) AND NOT X.End THEN
OUT.WriteLn ("Non-closed statement");
END;
END;
where one first tests for the existence of a feature named
End before actually using it. In this example, we use
RainCode support for lazy evaluation, in such a way that
an expression of the form
(X CAN End) AND NOT X.End does not abort: the second
member of the conjunction is only tested if the first member
evaluates to TRUE.