A TYPE defines the shape that a piece of data can take.
The grammar of a single TYPE line:
A TYPE keyword can live inside MODULE , TYPE , and FUNCTION keywords, or at the Root.
Declares a type whose full name is prefixed by the enclosing module.
Inside a module the module name becomes part of the type's full name, so this Point is the type Geometry.Point .
Nests a type under another type acting as a pseudo-module.
The outer type acts as a pseudo-module : Point is nested under its dotted name as an independent type, not a member.
Nests a type under a function acting as a pseudo-module.
The function acts as a pseudo-module ; the type is nested under its dotted name, independent of the function's own logic.
Declares a free type, named directly with no prefix.
With no enclosing declaration, the type is named directly and lives at the Root.
A type's members are either FIELD lines or OPTION lines — never a mix of the two; that is what makes a type a record or a union. Alongside them it may carry NATIVE lines and nested declarations as a pseudo-module (listed below).
A named, typed member of a record. The order of the fields is the order of the constructor's arguments, so Point 0.0 0.0 fills x then y , and reading somePoint.x is a reactive, reversible projection. A type that holds fields is a record.
A named variant of a union, carrying a payload type. The option name is both a constructor ( Shape.circle x ) and a reactive projection ( value.circle ) that yields an Optional of the payload. A type that holds options is a union.
A per-platform native representation of the type, one line per target — the host type the renderer uses for that language. A type may be all NATIVE lines when it is an opaque platform type (a native map or array, say), or pair them with fields or options that serve as the Program fallback where a target has no native line.
A nested module under the type's dotted name — the type acting as a pseudo-module , since a type is so often the centre of a module. Pure naming convenience.
Another type under this type's dotted name, acting as a pseudo-module . Pure naming convenience — an independent type, not a method.
A function under the type's dotted name, the type acting as a pseudo-module . It is completely independent and not a method: Text.Append does not belong to a Text value or receive one implicitly — it merely shares the Text prefix for tidy naming and takes whatever it operates on as a normal parameter.
A named constant under the type's dotted name, the type acting as a pseudo-module — a fixed value bound with a constant expression and reached through the type's name (as Colour.RGB.Black ). A declaration, not a field or a method.
The same two examples, rendered to each target. A record becomes the target's idiomatic struct or class; a union becomes its idiomatic sum type, one variant per option. The surface keyword is one, but the compiled form still distinguishes the two — a record is a ["D", …] node in the canonical JSON , a union a ["U", …] .
A record is every FIELD at once; a union is exactly one OPTION of several — the two are duals, and a field or an option may itself carry another type. A record is built by calling its type name positionally ( Point 0.0 0.0 ) and read with reactive value.field access; a union is built with the option name as constructor ( Shape.circle x ) and read with reactive value.option projection, which yields an Optional — itself just the built-in union with some and none options. A type may be given a native representation per platform with NATIVE lines, and a recursive union that holds a collection of itself is the model behind the JSON value type in Code.Language.Json . Back to the language .