Presentation

Declared Presentation — `FORMAT`, `VALIDATE`, `PRESENT`, `##` notes

Declared Presentation — FORMAT, VALIDATE, PRESENT, ## notes

A model's meaning lives in its formulas; how a value should look, what writes it accepts, and why it exists are usually scattered across UI state. Declared presentation brings all three next to the cell, in source:

## Quarterly revenue, gross of returns.
input revenue is currency = 100000
  FORMAT "$#,##0.00"
  VALIDATE BETWEEN 0 AND 10000000 MESSAGE "Revenue must be a positive dollar amount."

Record input fields can instead use a standalone VALIDATE FIELD declaration. It names an exact member path on the owning input; whole-input and field rules are checked together against the proposed batch. See the field-rule reference for syntax, limits and the development verification status. These contracts do not add a browser evaluator or extend write ownership to computed fields or private locals.

Clauses trail the declaration — inline or on directly following indented lines. They are declarations, not statements: the cell's formula stays exactly what it was.

Layering

Presentation resolves through four layers, weakest to strongest:

tag-implied default          a currency tag suggests currency rendering
  < tag policy               top-level FORMAT <tag> <expr>
    < declared per-cell      trailing FORMAT/VALIDATE clause, ## note
      < override layer       rule FORMAT actions + UI/API edits

RESET FORMAT x (a rule action) clears the override layer and drops back to the declared layer. Overridden cells report their provenance ("overridden (declared: …)") so a declared format is never silently lost.

Doc notes — ##

A ## line documents the next declaration; a trailing ## documents its own line:

## Discount applied before tax.
## Negotiated annually with the vendor.
discount = 0.15
 
tax_rate = 0.0875   ## City + state combined.

A blank line detaches a ## block, so decorative comment banners stay inert. Notes ride module metadata into the UI (cell inspection, tooltips) — they are documentation, not evaluated content.

FORMAT

Three placements, one vocabulary (spreadsheet format patterns):

price = 19.99 FORMAT "$#,##0.00"       # per-cell declaration
 
FORMAT percentage "0.0%"               # tag policy: every percentage-tagged cell
 
WHEN audit_mode THEN
  FORMAT price "$#,##0.0000"           # dynamic override from a rule
END

Format operands are expressions: FORMAT IF(compact_view, "$#,##0,,\"M\"", "$#,##0.00") re-derives when its inputs change. Tag policies resolve most-specific-first through the type lattice, so a USD policy beats a currency policy beats a number one.

PRESENT

A trailing PRESENT <Kind> chooses the usual Grid View element for a binding:

input qty = 2 VALIDATE 1..10 PRESENT Slider
SURFACE Order
  qty
  NumberInput qty
  show qty
END

The first line inside the view uses Slider; the second explicitly uses NumberInput; show qty remains a read-only presentation. The preference never changes the cell's formula, type, ownership, or validation. A control preference applies to editable placements and a display preference applies to read-only placements. The opposite direction uses its normal presentation.

The priority is an explicit kind on the view line, then the binding's PRESENT, then the most specific tag policy (PRESENT <tag> AS <Kind>), then the inferred root default. A preferred kind must accept the binding's subject type. local declarations can also carry PRESENT. Like FORMAT and VALIDATE, it may appear inline or on a directly following line, at most once per declaration.

VALIDATE

The clause vocabulary reuses the language's predicate keywords with the subject implicit:

input qty    is integer = 1        VALIDATE BETWEEN 1 AND 100
input qty2   is integer = 1        VALIDATE 1..100          # sugar for BETWEEN
input margin is percentage = 5pct  VALIDATE >= 0
input region = "EMEA"              VALIDATE IN ["EMEA", "AMER", "APAC"]
input invoice = ""                 VALIDATE LIKE "INV-%"
input code   = ""                  VALIDATE STARTS WITH "GRID-"

Accepted clause heads: the comparisons (=, <>, <, <=, >, >=), BETWEEN … AND … (and the lo..hi sugar), IN, LIKE / ILIKE, STARTS WITH, ENDS WITH, CONTAINS. An optional MESSAGE "…" supplies the rejection text. Bounds are expressions — VALIDATE 1..max_qty re-derives when max_qty changes.

VALIDATE means one of two things depending on where it sits:

On an input cell: a write contract

Every write surface — the grid UI and the model-binding ABI, so API and connector writes too — checks the incoming value (after type-tag coercion) against the clause. A rejected write returns the violation and leaves the cell unchanged. Native batched writes validate their complete proposed state before committing any member: a clause can depend on another input in the same batch, including a default restored by a clear. The detached check does not launch external work or commit rule events. Unresolved operands and unsupported clone capabilities refuse the batch. The contract gates writes only; changing a bound later does not retro-invalidate a stored value.

Grid View controls show the declared message for text predicates and text/Boolean equality before saving. Forms retain invalid drafts, read staged values for direct input operands, and refresh feedback when those inputs change. Computed operands continue to use committed native results. Numeric/structured equality feedback remains native-owned. See Grid Views for the canonical order-details example and Code's checked validation editor.

On a computed cell: a static assertion

The compiler's interval analysis propagates value ranges through formulas and discharges the assertion at compile time:

input x = 0 VALIDATE 0..1
y = x / (x + 1) VALIDATE 0..1    # proven — recorded in module metadata
z = x + 2      VALIDATE 0..1    # GRID_VALIDATE_UNSATISFIABLE: can never hold
w = x * 3      VALIDATE 0..1    # GRID_VALIDATE_UNVERIFIED: not provable

An input's write contract seeds the range other formulas observe — that is what lets y above be proven outright. Refuted assertions are warnings by default and hard errors under strict (see reference §5.4); unverified ones stay warnings, an honest signal that nothing checks the assertion at runtime.

Where clauses may not appear

Compound assignments (+=), graph bindings, and table bindings do not take presentation clauses — declare them where the cell is defined.

See also