nustack

Query

Value-producing atom. Computes from operands or reads from Context. Never transforms Context.

Properties

  • Mutation: none - declares no mutation slot. Its own tracked effects are ⊆ {READ}. (May be pure: no effects at all.)
  • Children: Queries only.
  • Yields: one value (Scalar) or N values (Stream); see sub-shapes below.

Sub-shapes

Sub-shapeYieldsSourceExamples
ScalarQueryone valueheld / operands / ref / streamLiteral(5), Add, Eq, ref.fetch(), Collect, First
StreamQueryN valuessource stream or ref collectionMap, Filter, Take, ItemsOf, KeysOf, ForEach

Literal is a notable Scalar: irreducible leaf, holds a value, yields it once. The trivial Query, pure (no effects). Worth flagging because most non-Ref leaves are Literals.

Composition

  • Q in Q. Functional composition: child yields a value, parent consumes it.
  • Iterator stacking. Filter(Map(ItemsOf(ref), x+1), x>0) - stream lenses stacked, no intermediate materialization.
  • Scalars over streams. A Scalar can consume a Stream child by pulling and folding (e.g. Collect(Filter(ItemsOf(ref), p)), First(stream)). This is what bridges the otherwise-REFUSED scalar-asks-stream cell of the realization matrix.

Forms

Literal(5)
Add(Literal(2), ref.fetch())
Map(ItemsOf(ref), x + 1)
Filter(Map(ItemsOf(ref), x + 1), x > 0)
Collect(Filter(ItemsOf(ref), p))
First(StreamQuery(...))

Examples

ExpressionSub-shapeEffects
Literal(42)Scalarpure
Add(Literal(2), Literal(3))Scalarpure
ref.fetch()ScalarREAD
Eq(ref.fetch(), Literal(0))ScalarREAD
If(cond_q, a_q, b_q)Scalarderived
ItemsOf(coll_ref)StreamREAD
Map(ItemsOf(ref), x+1)StreamREAD
ForEach(items, x+1)Streamderived
Collect(Filter(...))Scalarderived
First(stream_q)Scalarderived

Constraints

  • No Command children. Commands yield nothing - breaks the value chain.
  • No Flow children. Same reason - Flow yields nothing.
  • Action children allowed. Actions yield (Q's contract) and mutate Context (Q's old no-WRITE promise relaxes when Action is in play). A ScalarAction drops straight into a scalar slot; a StreamAction yields a stream, so a scalar Query reduces it like any StreamQuery. Q's yield-side contract is unchanged; its composition_effects may now include WRITE through Action descendants.

Why this kind

Computation composes naturally as functional expressions. Q is the algebraic backbone of the model: associativity, parallelism on independence, common-subexpression. Pure compute or Context-using read; never mutation.

Bare verb vs *Do

ForEach, If, Map are Queries (yield values, compose like expressions). The *Do variants (ForEachDo, IfDo) are Flows that compose Commands. Same author intent, different algebras. See kinds for the convention.

On this page