Summary
Unify type definition syntax so both records and unions use { } for fields/variants. Construction stays as ( ). Support inline nested unions.
Proposed syntax
Records
// No = needed, { } directly after name
type User {
name: string,
age: number,
}
// Record composition
type ButtonProps {
...BaseProps,
onClick: fn() -> (),
label: string,
}
Unions
// { } with | for variants
type Shape {
| Circle { radius: number }
| Rectangle { width: number, height: number }
| Point
}
Inline nested unions
type AppError {
| Network {
| Timeout { ms: number }
| DnsFailure { host: string }
}
| Payment {
| CardDeclined { reason: string }
| InsufficientFunds
}
| NotFound
| Auth { message: string }
}
Same pattern at every nesting level: `{ | ... }` is a union, `{ name: type, ... }` is fields.
Newtypes
Aliases and string literal unions (unchanged, still use =)
type Name = string
type Method = "GET" | "POST" | "PUT" | "DELETE"
Parser disambiguation
Peek at first token inside `{ }`:
- `|` → union (variants)
- lowercase `name:` → record (fields)
- bare type name → newtype wrapper
Construction unchanged
const u = User(name: "Alice", age: 30)
const c = Circle(radius: 5)
const id = OrderId(42)
// Matching nested unions — peel off layers
match error {
Network(Timeout(ms)) -> \`Timed out after \${ms}ms\`,
Network(DnsFailure(host)) -> \`DNS failed: \${host}\`,
Payment(CardDeclined(reason)) -> \`Card declined: \${reason}\`,
Payment(InsufficientFunds) -> "insufficient funds",
Network(_) -> "network issue",
NotFound -> "not found",
Auth(message) -> message,
}
One-line parsing
Works because `{ }` delimit groups unambiguously:
type AppError { | Network { | Timeout { ms: number } | DnsFailure { host: string } } | NotFound }
Current syntax (for reference)
// Record — uses = { }
type User = {
name: string,
age: number,
}
// Union — uses = |
type Shape =
| Circle(radius: number)
| Rectangle(width: number, height: number)
| Point
Scope
- Parser: type definition syntax for records and union variants
- Codegen: adjust type emission
- Checker: update type definition handling
- Support inline nested union definitions (compiler generates intermediate types)
- All .fl files, test fixtures, example apps
- Docs (design.md, llms.txt, site)
- Syntax highlighting (tree-sitter, TextMate)
Summary
Unify type definition syntax so both records and unions use
{ }for fields/variants. Construction stays as( ). Support inline nested unions.Proposed syntax
Records
Unions
Inline nested unions
Same pattern at every nesting level: `{ | ... }` is a union, `{ name: type, ... }` is fields.
Newtypes
Aliases and string literal unions (unchanged, still use =)
Parser disambiguation
Peek at first token inside `{ }`:
Construction unchanged
One-line parsing
Works because `{ }` delimit groups unambiguously:
Current syntax (for reference)
Scope