Skip to content

Type system

The full type system specification is still being written — it lives as a separate document from the grammar: the grammar describes how programs parse, the type system describes what they mean. A narrow slice of checking already runs in cmo check (see Status below); the spec below is where it’s headed.

The spec covers:

  • Unit typesTime, Length, Frequency, Angle, Tempo, and how the lexer’s units (ms, px, hz, deg, bpm, bars, beats, …) inhabit them.
  • Asset typesImage, Audio, Font, opaque to the program but loadable through the stdlib.
  • 2D typesPath, Layer, Frame, and the rules for compose [...].
  • 3D typesMesh3d, Material, Light, Camera, and the bridge from 3D back to a 2D Layer via render3d(...).
  • Color — a single Color type inhabited by every color_lit form (#hex, oklch(...), oklab(...), srgb(...)). Color space is part of the value, not the type, so mixing colors across spaces is allowed and well-defined.
  • Animation typesAnimation<T> parameterised by what’s being animated (Animation<Scale>, Animation<Color>, Animation<Angle>). animate { ... } with { ... } produces one of these.
  • Function types — including how animate { ... } with { ... } and postfix method chains are typed.
  • Determinism partition — every stdlib function is tagged pure or effectful. Effectful functions take an explicit capability (file/network/clock) and cannot be called from a pure context. This is what makes the CanvasKit backend deterministic.

Status: in progress. A narrow slice runs in cmo check — unit categories (a duration can’t be a length), name resolution, and literal-vs-annotation mismatches — with stable diagnostic codes (NAM*, TYP*, UNT*). The full type system above (generics, Animation<T>, function types, the pure/effectful partition) is the remaining work. See Roadmap stage 2.