Guards

Guards are special constructs used to catch NIL values in expressions. There are two guards, the ? and the | guard. The ? guard has high lexicographic precedence and is used with variables or parenthesized expressions:

X = A? + 1. // Terminate the transaction if A is NIL, otherwise add 1 and assign to X. 
Y = (B A)?. // Assign the result of (B A) to Y if it is not NIL or terminate with an error otherwise.

The | guard is used to prevent delayed errors in expressions using reductions. For example, if F is a collection of collections, you can subscript F twice, but you need to use a guard if you are not sure that the corresponding element exists:

C = (1->("A"->"B"), 2->("C"->"D")). 
X = C 3 | "A". // Terminates with an error if (C 3) does not exist

The | guard is technically not necessary because the error is produced anyway due to NIL not being subscriptable. However, using the guard is a good practice because it prevents NIL from leaking to downstream code causing hard-to-find bugs.

Guards as Casts

The ? and | guards are also casts that cast a nullable type into a non-nullable type, converting type X+ to a type X after required runtime checks.

X is int+ = NIL. 
// Y is int = X. // will cause a compile error because X is int+, which is not compatible with int
   Y is int = X?. // valid but produces runtime error if X is NIL

Declarative Cast

Declarative cast uses the keyword as and simply declares to the MUFL compiler that some value is compatible with a given type. For example, when assigning a string to a value list, it is sometimes important to declare that the value is compatible:

metadef theEnum:<$a,$b,$c>.
A is theEnum+ = NIL. 
B is str = "a". 
// invalid: A->B. 
A -> B as(theEnum). // This is valid, but BE CAREFUL!

safe Cast

A safe cast generates runtime code to check the validity of the value:

metadef theEnum:<$a,$b,$c>.
A is theEnum+ = NIL. 
B is str = "WRONG".  
A -> B safe(theEnum). // Does not cause a compile error, but fails at runtime because B is not compatible with A