v6 Types: static guarantees for a dynamic VM
Lesson, slides, and applied problem sets.
View SlidesLesson
v6 Types: static guarantees for a dynamic VM
We keep the runtime dynamic, but add a static type checker. This gives:
- earlier errors
- clearer interfaces
- safer refactors
Type syntax
number | bool | string | nil
array<type>
map<keyType, valueType>
fn(type, type) -> type
Examples:
let n: number = 1;
let names: array<string> = ["a", "b"];
let counts: map<string, number> = {"a": 1};
fn add(a: number, b: number) -> number { return a + b; }
Where types appear
- variable declarations:
let x: number = 1; - function params:
fn f(x: number) -> number { ... } - function return type: required
Assignability rules
- Exact type matches are required.
nilis assignable to any type (but still has no operations).- Arrays/maps/functions must match structurally.
Inference (small but useful)
- If a variable has no annotation, its type is inferred from the initializer.
- Empty arrays/maps require an annotation.
Operator typing (summary)
+: number+number => number, string+string => string- * /: number => number- comparisons
< <= > >=: numbers => bool && || !: bool => bool== !=: same types (or with nil)
We keep these rules strict to make errors crisp and readable.