Choices
A choice is a special kind of class that is Frost's version of what is commonly
known as a "sum type" or "tagged union". The simplest form of choice is very similar to a C
enumeration:
choice Direction {
NORTH
SOUTH
EAST
WEST
}
This creates a class with four possible values: Direction.NORTH, Direction.SOUTH,
Direction.EAST, and Direction.WEST.
Choice values may also have additional data attached to them:
choice Expression {
LITERAL(Int)
ADD(Expression, Expression)
SUBTRACT(Expression, Expression)
MULTIPLY(Expression, Expression)
DIVIDE(Expression, Expression)
}
In this case Expression has five possible states. An Expression.LITERAL contains a single Int,
and the other four types of expression contain two Expression children. Using this class, we could
represent the expression 3 + 6 as Expression.ADD(Expression.LITERAL(3), Expression.LITERAL(6)).
To extract values from an Expression, we need to use a match statement to
destructure it:
choice Expression {
LITERAL(Int)
ADD(Expression, Expression)
SUBTRACT(Expression, Expression)
MULTIPLY(Expression, Expression)
DIVIDE(Expression, Expression)
@override
function get_toString():String {
match self {
when Expression.LITERAL(v) { return v.toString }
when Expression.ADD(a, b) { return "\{a} + \{b}" }
when Expression.SUBTRACT(a, b) { return "\{a} - \{b}" }
when Expression.MULTIPLY(a, b) { return "\{a} * \{b}" }
when Expression.DIVIDE(a, b) { return "\{a} / \{b}" }
}
}
}
As shown above, choices are a kind of class and may contain user-defined methods, but they may not contain fields (other than constants).
Default Methods
Choices which do not override Object.get_toString will receive a default implementation that
returns the name of the choice and its data, such as LITERAL(3).
If all of the data elements of a choice implement Equatable, the choice itself will implement
Equatable. If an Equatable choice does not contain an implementation of the = operator, it
will receive a default implementation.
If all of the data elements of a choice implement HashKey, the choice itself will implement
HashKey. If a HashKey choice does not contain an implementation of the hash() function, it
will receive a default implementation.
Of course, if a choice does not contain any data elements (such as the Direction example above),
it is trivially true that all of its data elements implement Equatable and HashKey. Thus
Direction will implement both of these interfaces.
postInit
If a choice declares a postInit() method, it will be called after the choice is constructed. This
gives you an opportunity to perform error checking or other required setup.