Cure v0.13.0: The Type System Grows Teeth
by Aleksei Matiushkin
v0.12 gave Cure a body. v0.13 gives it teeth.
The headline: when you write fn safe_divide(a: Int, b: Int) -> Int when b != 0,
the compiler now actually checks that constraint at every call site. Call
safe_divide(10, 0) and Z3 proves the violation before a single BEAM
instruction runs. Call safe_divide(10, x) where x came from user input
and the compiler tells you it cannot prove the constraint – your job to
handle it.
This is not a runtime check. This is a compile-time proof.
What changed
Seven things, each deepening a subsystem that v0.12 established.
1. Dependent type verification
Functions with when guards now register as constrained types:
fn safe_divide(a: Int, b: Int) -> Int when b != 0 = a / b
fn positive_double(x: Int) -> Int when x > 0 = x * 2
At call sites, the compiler substitutes literal arguments into the guard predicate and sends it to Z3. If the predicate is unsatisfiable after substitution, you get a warning with a counterexample from the solver.
2. Protocols that cross module boundaries
Every impl is registered in a global ETS table during compilation. When
you compile Std.Show, the registry learns that :std_show provides
show/1 for Int, Float, String, Bool, and Atom. This is the foundation
for cross-module dispatch.
3. LSP improvements
Go-to-definition, document symbols (hierarchical outline), and code actions: quick-fix for non-exhaustive matches and did-you-mean suggestions for unbound variables.
4. Five optimizer passes
Inline (small pure non-recursive functions), constant fold, dead code elimination, pipe chain inline, and guard simplification (algebraic boolean rules).
5. FSM guards and actions
Transitions now support when guards and do actions:
fsm Counter
Counting --tick when count > 0 do count = count - 1--> Counting
Counting --tick when count == 0--> Done
6. Structured errors with source context
Error codes E001-E005, source line display with caret, cure explain E001.
7. Four new stdlib modules
Std.Map (14 fns), Std.Set (11 fns), Std.Option (10 fns), Std.Functor (1 fn). Total: 17 modules, ~200 functions.
The numbers
606 tests. Zero credo issues. Zero compilation warnings. 48 Elixir source files.
The repository is at github.com/am-kantox/cure.