nustack

Command

Persistence atom. Takes computed values and a target Ref, transforms the Context. Yields nothing.

Properties

  • Mutation: declares at least one mutation slot, and it must hold a Ref.
  • Children: Queries only.
  • Yields: nothing.

Sub-shape

Effectively one: ScalarCommand. A single mutation. Children supply the value(s) and the address(es).

There is no StreamCommand. A Command yields nothing, so the scalar/stream realization split doesn't apply.

Forms

Store(ref, value_q)            # write value at address
Copy(src_ref, dst_ref)         # value at src -> dst
Append(list_ref, value_q)      # append value to list
Delete(ref)                    # remove location

Examples

ExpressionEffects
Store(ref, Literal(42))WRITE
Store(ref, Add(ref.fetch(), 1))READ + WRITE
Copy(src_ref, dst_ref)READ + WRITE
Delete(ref)WRITE

Constraints

  • No Command children. A Command yields nothing; Command's value-needing slots have no value to consume.
  • No Flow children. Same reason - Flow yields nothing.
  • Action children allowed. Actions yield a value (the payload or address), so they fit any value-needing slot - including Command's. The WRITE Action carries lands as another tracked effect alongside Command's own.
  • The mutation slot must hold a Ref. That's how the WRITE lands. A Command yields nothing, so a non-Ref (addressless) mutation slot would leave it non-observable - it voids. (Unlike Action, which survives on its yield. See 04-action.md.)

Command vs Action

Command yields nothing; Action both mutates and yields. Where the world admits a clean separation (write a value, no return), use Command. Where the world refuses it (Pop, Create, INSERT ... RETURNING), use Action. See 04-action.md.

Why this kind

The boundary between compute and mutate. Where computed values become observable in the Context. The terminal atomic act: Refs name the place, Queries supply the value, the Command does the write.

On this page