Enums and flags

Enums

An enum value has a fixed set of possibilities.

main void() log opposite left direction enum left right == bool(a direction, b direction) to json(a direction) opposite direction(a direction) if a == left right elif a == right left else throw unreachable

Short enums can be squeezed onto a single line.

direction enum(left, right)

Enums support all the same auto functions as records, plus functions for converting to/from numbers and symbols.

main void() log "compare", left <=> right log "to symbol", left.to::symbol log "from symbol", "left".to::direction? log "from wrong symbol", "both ways".to::direction? log "to nat", left.to::nat log "from nat", 1.to::direction? log "from wrong nat", 2.to::direction? log "all members", members::direction[] direction enum(left, right) == bool(a direction, b direction) <=> comparison(a direction, b direction) hash void(a direction, state hash-state) to json(a direction) to symbol(a direction) to direction?(a symbol) to nat(a direction) to direction?(a nat) members direction[]()

"match" on enums

A more convenient way to use an enum is with a match expression.

main void() log opposite left direction enum(left, right) to json(a direction) opposite direction(a direction) match a as left right as right left

Enum numbers

You can customize the number values used for the enum.
This currently only supports nat values.

main void() log left.to::nat direction enum left = 5 right = 10 to nat(a direction)

to could also return a nat8, nat16, or nat32, though only if the maximum enum value fits into the type.

Flags

A flags value can contain any combination of the declared flags.

main void() apple = carry | eat | toss soup = carry | eat rock = carry | toss log "apple picnic?", can-picnic apple log "soup picnic?", can-picnic soup log "rock picnic?", can-picnic rock log "flags a rock lacks:", ~rock log "rock and soup have in common:", rock & soup log "flags in either rock or soup:", rock | soup actions flags carry eat toss to json(a actions) can-picnic bool(a actions) a[carry | eat]

Declaring a flags type implicitly defines several additional functions. The above example defines:

FunctionUse
new actions()Value with no flags set.
carry actions()Value with just the carry flag set.
eat actions()Value with just the eat flag set.
toss actions()Value with just the toss flag set.
~ actions(a actions)Value with the opposite flags set.
| actions(a actions, b actions)Union; contains any flags that appear in either argument.
& actions(a actions, b actions)Intersection; contains only the flags that both arguments agree on.
subscript bool(a actions, b actions)True if a contains every flag in b. Written as a[b].

flags types also support all the usual auto functions.