Enum / union type — design
Need a type for a fixed set of values. Three candidates with different semantics.
Candidate 1: C#-like enum (named constants)
Enum = set of named constants. By default — standalone type. With explicit base type — alias for constants of that type.
# Standalone type (from some)
type color = | red | green | blue
c = color.red
print(c) # 'red'
c == color.green # false
# With base type — alias for int
type httpStatus: int = | ok = 200 | notFound = 404 | error = 500
s = httpStatus.ok # 200 : httpStatus (= int)
s + 1 # 201 : int (arithmetic works)
# With base type text
type direction: text = | north = 'N' | south = 'S' | east = 'E' | west = 'W'
Properties:
- Enum value == value of base type (or unique singleton)
- `==` works
- Exhaustive when: compiler checks completeness
- Without base type: `color.red != 0`, `color.red != 'red'` — separate type
Candidate 2: Tagged union (sum type)
Each variant can carry data. Like Rust enum, Haskell ADT.
type shape
| circle(radius: real)
| rect(width: real, height: real)
| point
area = when s of shape:
circle(r): pi * r * r
rect(w, h): w * h
point: 0
Properties:
- Each variant is a constructor with optional fields
- Pattern matching with destructuring
- Exhaustive when
- Significantly more complex in TIC (variant types, pattern destructuring)
Candidate 3: Sealed struct hierarchy
Combination of struct + type constraint. No new syntax needed.
type shape = { kind: text }
circle(r) = { kind = 'circle', radius = r }
rect(w, h) = { kind = 'rect', width = w, height = h }
area = when s.kind:
'circle': pi * s.radius * s.radius
'rect': s.width * s.height
Properties:
- No new type in TIC needed
- Pattern matching by field value
- No exhaustive check (kind = any text)
- No type safety — typo in kind not caught
Comparison
| Property |
C#-like enum |
Tagged union |
Sealed struct |
| Data in variant |
no |
yes |
yes (via fields) |
| Exhaustive when |
yes |
yes |
no |
| TIC complexity |
low |
high |
zero |
| Pattern destructuring |
no |
yes |
no |
| Subtypes |
base type |
no |
row polymorphism |
| Implementation |
medium |
complex |
already works |
Questions
- Is tagged union needed or is C#-like enum sufficient?
- If tagged union — how does it fit TIC? New StateVariant?
- Can we start with enum (simple), add union later?
- `|` — does it conflict with bitwise OR? (currently `|||` for bitwise)
- Is `of type` syntax in when needed for exhaustive check?
Enum / union type — design
Need a type for a fixed set of values. Three candidates with different semantics.
Candidate 1: C#-like enum (named constants)
Enum = set of named constants. By default — standalone type. With explicit base type — alias for constants of that type.
Properties:
Candidate 2: Tagged union (sum type)
Each variant can carry data. Like Rust enum, Haskell ADT.
Properties:
Candidate 3: Sealed struct hierarchy
Combination of struct + type constraint. No new syntax needed.
Properties:
Comparison
Questions