24.17.5 exception-predicate

It is often needed to determine whether the execution of some given code raised some particular exception. A possibility is to use a try-catch statement like in the following example, a pretty-printer in an union type:

method _print = void:
{
  try print "#<%u32d>", simple_value;
  catch if E_elem { print "%v\n", complex_value; }
}

This works as intended, but it is somewhat verbose and not that easy to read for anyone not accustomed to the idiom. It is better to use the exception predicate operator, ?!, that has two forms:

exp ?! exception
{ [statements...] } ?! exception

In the first form, the expression exp is executed. If the execution raises the exception exception then the result of the predicate is 1 (true), otherwise it is 0 (false). The value of the expression is discarded.

In the second form, the compound statement passed as the first operand is executed. If the exception exception is raised, then the result of the predicate is 0 (false), otherwise it is 1 (true).

Using exception predicates the pretty-printer above can be written in a much more readable way:

method _print = void:
{
  if (simple_value ?! E_elem)
    print "%v\n", complex_value;
  else
    print "#<%u32d>", simple_value;
}

Or, alternatively (and slightly more efficiently):

method _print = void:
{
  ({ print "<%u32d>", simple_value; } ?! E_elem)
    && print "%v\n", complex_value;
}