v6 Types: static guarantees for a dynamic VM

Lesson, slides, and applied problem sets.

View Slides

Lesson

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.
  • nil is 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.


Module Items