SDA reference

The exact shaping contract, for when you need selectors and projection precisely.

SDA (Structured Data Algebra) is the small, pure language Crisptastic pages use to reshape data — through the @shape directive and the sda(value, query) built-in. This page is the exact contract; for the motivation and everyday use, start with Data shaping.

Execution model

  • An SDA program evaluates to a value or to Fail(code, msg). There is no partial result and no exception.
  • It is pure: no ambient I/O, no clock, no randomness. The only inputs are the value you pass in and the fixed helper functions.
  • It is deterministic: the same input and program always produce the same result.
  • Evaluation order is observable only for ordered sequences.

Value kinds

Null   Bool   Num   Str   Bytes
Seq    (ordered)
Set    (unordered, unique)
Bag    (unordered, multiplicity kept)
Map    (keyed)
Prod   (fixed-shape record)

Seq compares positionally. Set, Bag, Map and Prod compare extensionally — by contents, not construction order.

Absence, Null and Fail

Three distinct things, never conflated:

  • absence — a key or element that isn't there;
  • Null — a present value that is explicitly null;
  • Fail(code, msg) — the transformation could not proceed.

Optional extraction turns absence into a usable default; required extraction turns absence into Fail.

Query surface

  • Selectors.field, .a.b, .[i], .[] (each element).
  • Comprehensions — map / filter that preserve the carrier kind.
  • Predicates — a small comparison and boolean language for filters.
  • Projection{ a, b: .other, c } builds a Prod.
  • Pipesexpr | expr | expr, left to right.
  • Helpers — a fixed set for sorting, taking, normalising and cleaning keyed collections.

Bindings

Bindings are lexical and immutable. There is no assignment and no mutation of the input.

The full formal grammar and the complete helper list are in docs/specs/sda/ in the repository.