Enums define a type with a fixed set of variants. They compile to C tagged unions.
Tag-only Enums
The simplest form: a named set of variants with no attached data.
enum State { Idle, Running, Jumping, Dead }
@state :: script = State.Idle
def on_tick(dt :: float) do
if @state == State.Idle do
print("waiting")
end
endCompare enum values with == and !=.
Payload Enums
Variants can carry data. Each variant can have a different payload type:
enum Shape {
Circle(float),
Rect(float, float),
Point
}Point carries no data. Circle carries a float (the radius). Rect carries two floats (width and height).
Payload enums are most useful with case/when pattern matching, see Pattern Matching.
Pattern Matching on Enums
defp describe(s :: Shape) :: string do
case s do
when Circle -> "a circle"
when Rect -> "a rectangle"
_ -> "a point"
end
endState Machines
Tag-only enums are the natural fit for game state machines:
enum GameState { Menu, Playing, Paused, GameOver }
@gs :: script = GameState.Menu
def on_tick(dt :: float) do
if @gs == GameState.Menu do
if key_pressed(:enter) do
@gs = GameState.Playing
end
end
if @gs == GameState.Playing do
update_game(dt)
if @lives <= 0 do
@gs = GameState.GameOver
end
end
if @gs == GameState.Paused do
if key_pressed(:escape) do
@gs = GameState.Playing
end
end
endAtoms vs Enums
Atoms (:idle, :running) and enums both represent named constants. The practical difference:
| Atoms | Enums | |
|---|---|---|
| Declaration | None, write them anywhere | Requires enum block |
| Type checked | No (type is atom) | Yes (type is EnumName) |
| Payload | No | Yes (payload enums) |
| Best for | Quick tags, case arms | Defined sets of variants with type safety |
Use atoms for quick prototyping or when the set of values is open-ended. Use enums when you want the compiler to enforce the valid set.