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 aProd. - Pipes —
expr | 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.