Values and comprehensions
A report can contain scalar data while its query retains native domain handles.
ConstructedValue holds the data part: Booleans, signed integers, finite floats, strings,
resolved nominal members, positional arrays, tuples, records, typed sets and
explicitly keyed arrays. A host handle becomes scalar data only through an
explicit host projection.
Expression trees
Section titled “Expression trees”ValueExpression is a located expression tree. It supports literals and names,
collection construction, checked scalar operations, access, inclusive integer
ranges, conditional branches and comprehensions. A host parser lowers its syntax
to this tree. The getting started example evaluates one
without a frontend.
The embedding guide describes validation, evaluation and copying APIs for this representation.
Use the same request budget across these operations. There is no deep Clone
implementation that bypasses copy accounting. Records preserve their written
labels and order; duplicate labels fail. Positional arrays and tuples use
positive one-based access positions.
Checked arithmetic and conditions
Section titled “Checked arithmetic and conditions”Integers use i64. Overflow and division by zero fail. Integer division truncates
toward zero; remainder has the dividend’s sign. Dividing or taking the remainder
of i64::MIN by -1 also fails. Mixed integer/float operations require exact
integer-to-binary64 promotion. Strings receive no numeric coercion.
Floats must stay finite. Nonzero floating arithmetic rounded to zero fails.
Because an f64 literal has lost its decimal spelling, a frontend must also
reject a nonzero decimal literal that parses to zero.
Boolean operations short-circuit, and conditionals evaluate only the selected
branch, with a required final else. Known incompatible types still fail validation
in skipped branches. A skipped missing access or zero division is not evaluated.
ValueType::Unestablished records missing type facts; it is not a runtime null or
an Unknown Boolean.
Positional comprehensions
Section titled “Positional comprehensions”An array comprehension walks its generator clauses in order, evaluates each source before introducing its own binders and evaluates the head after filters. Later clauses can refer to earlier binders. Local binders are restored on success and failure.
A word host can project birch apple ash apple to UTF-8 byte lengths
[5, 5, 3, 5]. A comprehension can filter out the short word and double the
remaining lengths. Written here as notation for the expression tree:
[n * 2 for n in [5, 5, 3, 5] if n > 3]→ [10, 10, 10]The current Rust representation uses ValueExpressionKind::Comprehension with
ValueConstructor::Array or Set and ValueGenerator clauses. Grouped binders
form a Cartesian product. Source order determines array result order. Set
construction removes equal elements and uses type order. Supported scalar set
identities are Boolean, integer, float and resolved nominal member; strings are
not set elements in this implementation.
Every candidate is charged before filtering, including candidates a filter rejects.
Nominal members
Section titled “Nominal members”A nominal member carries a host-supplied NominalTypeId and NominalMemberId,
retained type/member names and declaration order. Equality uses the IDs within
one immutable host context for the request. Equal names do not establish identity.
Member sets use declaration order. Contradictory metadata, mixed nominal types
and member arithmetic fail.
The host establishes these members and their identities. Zirql does not load or execute a domain model to discover them.
Keyed arrays
Section titled “Keyed arrays”A keyed array retains typed, ordered axes and sparse cells. It is distinct from a
positional array or nested arrays. A rank-one array may use integer keys 2 and
5; it does not silently invent keys 3 and 4. A higher-rank cell has one key
component per dimension.
Native KeyedEntry values must have unique full keys in row-major axis order,
with the rightmost dimension varying fastest. A lowered KeyedArray expression
can accept pairs in written order and normalize them. Supplied axes keep their
explicit order; inferred axes use numeric or member declaration order.
A keyed comprehension evaluates keys and heads after filters. Sparse output is
valid in the shared core. An empty result still needs typed axes. Its
empty_axis_sources can establish those from integer/member arrays or typed sets,
using the surrounding scope outside this comprehension’s binders. Nonempty
results do not evaluate these fallbacks.
Array access checks key types and rank. index_set requires rank one and returns
the typed axis as a set in numeric or declaration order. A host may require
contiguous axes or complete rectangular coverage even though the core supports
sparse cells. See semantic model integrations for a
concrete example of that boundary.