Version: dev

Operators

The expression vocabulary: what each operator does, its arguments, and its result.

An expression is one of four things:

FormJSONMeaning
Number2, 1.5e-9A literal. Integer and float tokens are distinguished.
Variable"O3"A reference to a variable, parameter, species, or index.
Operator node{"op": …, "args": […]}An application.
Scoped reference"Chem.O3"A dotted path into a subsystem.

An operator node always has op and args. Some operators take extra named fields — wrt on D, output_idx/ranges on faq, regions/values on makearray — which are listed on each operator’s page.

Text

k * A * B

JSON

{ "op": "*", "args": ["k", "A", "B"] }

Two tiers

Evaluable core (closed). The operators in the index below have a defined evaluator in every binding. The set is closed: adding one is a specification change. That closure is what lets a conforming reader in any language evaluate any document without executing author-supplied code.

Rewrite-target (open). grad, div, laplacian, integral, a D with a spatial wrt, and any operator you invent have no evaluator. They must be eliminated by a template rewrite before evaluation. A document may load with them present; one that reaches evaluation still carrying them is rejected with unlowered_operator.

A rewrite-target operator gets no privileges: its result dimension is unknown until it is lowered, and no binding may special-case its name. A custom op carries its scheme parameters in attrs rather than in dedicated fields.

Text form

Every example on these pages is one expression shown two ways: a block labelled Text, the notation an author writes, followed by a block labelled JSON, the node it denotes. They are not two different examples, and they are not independent — each pair is checked with the shipped parse_expression and to_ascii, which are inverses, so the text parses to exactly the JSON shown and the JSON prints back to exactly the text.

Multiplication is always explicit (k * A, never kA), because identifiers are multi-letter.

A JSON block with no Text partner is a form the text notation cannot spell today. broadcast and enum have no surface of their own — the first prints as the operator it applies, the second as a dotted name that re-parses as a scoped variable reference. neg shares the surface of unary -. And a few forms lose a field on the way out: a D carrying trailing boundary operands, a grad carrying dim, and an overlap join. Whole .esm documents are shown as JSON throughout; the text notation covers expressions and equations, not files.

Index

OpArityReference
+n-aryarithmetic, comparison, logic
-1 or 2arithmetic, comparison, logic
*n-aryarithmetic, comparison, logic
/2arithmetic, comparison, logic
^2arithmetic, comparison, logic
neg1arithmetic, comparison, logic
== != < <= > >=2arithmetic, comparison, logic
and or2+arithmetic, comparison, logic
not1arithmetic, comparison, logic
exp log log10 sqrt1elementary functions
abs sign floor ceil1elementary functions
sin cos tan asin acos1elementary functions
atan1 or 2elementary functions
atan22elementary functions
sinh cosh tanh asinh acosh atanh1elementary functions
min max2+elementary functions
ifelse3constants and conditionals
Pre1constants and conditionals
const0 (value field)constants and conditionals
true0constants and conditionals
enum2 string literalsconstants and conditionals
D1 (structural)calculus
ic1calculus
index1+arrays
makearray0 (regions/values)arrays
broadcast1+ (fn field)arrays
reshape transpose1arrays
concat1+arrays
faqstructuralaggregation
argmin argmaxstructuralaggregation
skolemn-aryaggregation
rank1aggregation
intersect_polygon2geometry
polygon_intersection_area2geometry
fnn-ary (name field)closed functions
table_lookup0 (table/axes)closed functions
apply_expression_templatestructural (bindings)expression templates

Arity structural means the operator’s operands live in dedicated fields rather than in args, and are described on its own page.

Rewrite-target sugar — grad, div, laplacian, integral, and a spatial D — is covered on the calculus page. It is not part of the set above.

Dimensional rules

Dimensional analysis follows the operator, and findings are warnings: a dimensional problem never makes a document invalid.

ClassOperatorsRule
transcendentalexp, log, log10, sinh, cosh, tanh, asinh, acosh, atanhargument must be dimensionless; result dimensionless
circularsin, cos, tanargument must be an angle; result dimensionless
inverse circularasin, acos, atan, atan2argument dimensionless; result an angle
comparison<, <=, >, >=, ==, !=operands must share a dimension; result dimensionless
booleanand, or, notoperands dimensionless; result dimensionless

Everything else either propagates its operands’ dimension (+, -, min, max, ifelse) or combines them (*, /, ^). A rewrite-target operator has no rule, so a checker reports unknown and skips the enclosing check.