The WHAT control structure can be used to test the dynamic type of an expression:
METHOD Dump(p: Polygon);
VAR
Sizes: ARRAY OF INTEGER;
i: INTEGER;
BEGIN
WHAT p OF -- p is the discriminant expression
IN Square:
-----------------------------
-- TAG is a Square or a Square-compatible item
-----------------------------
InOut.WriteString("Square size: ");
-----------------------------
-- Size is a Square-specific method;
-- hence it can be applied to TAG.
-----------------------------
InOut.WriteInt (TAG.Size, 4);
END;
IN Rectangle:
-----------------------------
-- TAG is a Rectangle or a Rectangle-compatible item,
-- except for the fact that it cannot be a Square since
-- the first alternative would have been selected if it was.
-----------------------------
InOut.WriteString("Rectangle size:");
-----------------------------
-- SizeX and SizeY are Rectangle-specific methods;
-- hence they can be applied to TAG.
-----------------------------
InOut.WriteInt (TAG.SizeX, 4);
InOut.WriteInt (TAG.SizeY, 4);
END;
IS Triangle:
-----------------------------
-- TAG is a Triangle here and nothing else.
-----------------------------
InOut.WriteString ("Triangle size: ");
Sizes := TAG.Sizes;
ASSERT Sizes.HIGH = 3; -- How good
-- is a triangle,
-- otherwise ?
FOR i := 0 TO 2 DO
InOut.WriteInt(Sizes [i], 4);
END;
END;
ELSE
InOut.WriteString("Any other polygon");
END;
InOut.WriteLn;
END Dump;
The WHAT control structure is made of an array of possible alternatives. Every alternative can be marked as IN or IS a class. An alternative is said to match when the discriminant expression's runtime type is (IS case) or is derived from (IN case) its attached class.
The statement sequence attached to the first matching alternative is executed, all subsequent alternatives are ignored. Inside the statement list attached to an alternative, the discriminant expression can be accessed as an instance of the alternative's class through the predefined variable TAG. In the example above, in the statement list attached to the alternative marked as IN Square, the discriminant expression p can thus be accessed as a Square through TAG.
The WHAT control structure ensures that YAFL's runtime system never has to perform any type checking, as opposed to the type testing that can be used by the programmer in a safe context.
It is true that the WHAT control structure poorly supports the object-oriented paradigm, and that polymorphism should be used whenever possible (in the example presented above, a deferred Dump method should be attached to the Polygon class, and redefined for the various derived classes). A large number of WHAT statements is an unmistakable symptom of a poor class structure. However, in practice, such a construct happens to be needed (even Eiffel provides a similar feature), and it is preferable to provide it in a controlled environment rather than leaving the entire reponsibility of the safeness of the operation to the programmer.