Skip to content

Glossary

Every term the rest of the documentation leans on. Written last, from the words the other pages actually needed.

Binding: a name for a value, written let. Computed at most once per evaluation however many names read it. Private to the program.

Output: a name whose value leaves the program, written output. Which names may be outputs is declared outside the program; see port layer.

Input: a value the program reads but does not compute, written $name. Supplied by the host, or by a user typing into a pane.

Op: short for operator, a named function with named inputs and one output. Everything that computes is one. Supplied by the standard library or by the host.

Symbol: surface syntax for an op, registered alongside it. + is the symbol for Add. Symbols are rewritten during parsing and leave no trace afterwards, and one symbol may expand into more than one op call.

Template: text with holes, `n = {count}`. Sugar over Join, which converts each hole to text; a hole is {…}, since $ means an input.

Lambda: a function written inline, item => item > 10. A value like any other, with real lexical closure over what surrounded it.

Higher-order op: an op with a function-typed input, such as Filter. Not a special kind of op; just an op whose input happens to be a function.

Strongly normalising: every program finishes. Guaranteed by two rules: a name cannot refer to itself, and a function is never accepted where any is expected. See the type system.

Named type: a type registered in the language’s table, identified by its name: number, Bus.

Structural type: an array or a function type, built from other types rather than registered. Two are the same type when their parts are.

any: accepts any data value, in both directions, and never a function. The escape hatch a host uses when it does not know a value’s type. Each crossing warns.

null: the value an unset input holds, accepted wherever a data value is expected, so a program over unset inputs still runs.

extends: a named type declaring a parent. Compatibility walks the chain.

Annotation: a type stated on a binding, let rows: number[] = …. A claim the checker holds the value to, with no check at runtime, so an any source still warns there.

Cast: value as type, a check at runtime. The value when it fits the type, null when it does not; never a throw, never a changed value.

Covariant, contravariant: which way a type may vary and stay compatible. Arrays are covariant in their element; functions are contravariant in their parameters and covariant in their return.

Vocabulary: what a language has: types, ops, evaluators, symbols. Deliberately not inputs and outputs.

Descriptor: what a program is actually checked against: a vocabulary with port layers composed onto it. Built per program.

Raw program: the parsed program: bindings and outputs as untyped AST nodes. The form that gets stored.

Core program: the analysed program: types resolved, dependsOn computed, unreachable bindings pruned. What runs, and rebuilt rather than stored.

dependsOn: per node, the set of input names it reaches. Computed once during analysis; the whole basis of incremental evaluation.

Pruning: dropping the bindings no output can reach, at the end of analysis. They warn on the way out.

Diagnostic: an error or a warning about a program. An error stops the output that depends on it; a warning changes nothing. A runtime failure is not a diagnostic: it arrives on the outputs.

Ports: a bundle of declarations: inputs, outputs, and the types they need.

Port layer: ports plus an id plus a policy. Layers stack, and the first to claim a name keeps it.

Policy: three fields on a layer: editable, feeds, persisted. Core reads the fields and never branches on a layer’s kind.

Persisted layer: the one layer saved with the program: the document’s own declarations. At most one per instance.

Provenance: which layer placed each name. What lets an editor say where a declaration came from and who may change it.

Global versus program level: a layer on the runtime, shared by every program on it, versus a layer on one instance.

Environment: a language wrapped with its pipeline. A program environment is one bound to a composed descriptor, and only that one can analyse.

Runtime: many programs over one language and one set of global layers, with shared input values.

Instance: one program on a runtime, with its own layers, its own values, and the observables a host watches. The front door for a host.

Stale: the outputs on screen came from a program that is no longer the one in the editor. Real values, flagged, not hidden.

Snapshot: everything a save would capture: the program, its ports, and its input values.

Host: the application embedding Dendrite. Declares inputs and outputs, supplies values, acts on outputs, and may add ops and types.

Connection: how an editor reaches a program: its own stack, a runtime the host runs, or an instance the host already has.

Replica: an instance reached across a channel by @dendrite-lang/link, indistinguishable from a local one to the editor.

Trust boundary: the serving side of a link. Policy is enforced there, because a replica’s messages are input, not instruction.