Skip to main content

Node

Enum Node 

Source
pub enum Node {
Show 70 variants Lit(i64), FloatLit(u64), FloatOp { op: BinOp, lhs: NodeHash, rhs: NodeHash, }, IntToFloat(NodeHash), FloatToInt(NodeHash), DecimalLit(i64), DecimalOp { op: BinOp, lhs: NodeHash, rhs: NodeHash, }, IntToDecimal(NodeHash), DecimalToInt(NodeHash), DecimalRaw(NodeHash), Bool(bool), Not(NodeHash), Str(String), StrLen(NodeHash), StrLower(NodeHash), StrFromCode(NodeHash), StrConcat(NodeHash, NodeHash), StrSlice { s: NodeHash, start: NodeHash, len: NodeHash, }, StrEq(NodeHash, NodeHash), StrContains { haystack: NodeHash, needle: NodeHash, }, StrStartsWith { s: NodeHash, prefix: NodeHash, }, StrIndexOf { haystack: NodeHash, needle: NodeHash, }, NumberToStr(NodeHash), StrToNumber(NodeHash), StrToNumberOpt(NodeHash), Now, List(Vec<NodeHash>), ListEmpty { elem: Type, }, ListCons { head: NodeHash, tail: NodeHash, }, OptionSome(NodeHash), OptionNone { elem: Type, }, OptionElse { opt: NodeHash, default: NodeHash, }, OptionMatch { opt: NodeHash, some_bind: String, some_body: NodeHash, none_body: NodeHash, }, ListTryGet { list: NodeHash, index: NodeHash, }, ListLen(NodeHash), ListGet { list: NodeHash, index: NodeHash, }, Map(Vec<(NodeHash, NodeHash)>), MapGet { map: NodeHash, key: NodeHash, }, MapTryGet { map: NodeHash, key: NodeHash, }, MapLen(NodeHash), Log(NodeHash), Publish(NodeHash), SetHeader { name: NodeHash, value: NodeHash, }, Rand, MutNew(NodeHash), MutGet(NodeHash), MutSet { cell: NodeHash, value: NodeHash, }, DiskWrite { path: NodeHash, content: NodeHash, }, DiskRead(NodeHash), NetGet(NodeHash), DbQuery { sql: NodeHash, params: NodeHash, }, Ref(String), Call { func: String, args: Vec<NodeHash>, }, FuncRef(String), CallValue { callee: NodeHash, args: Vec<NodeHash>, }, Lambda { params: Vec<Param>, body: NodeHash, }, Hole { expects: String, }, BinOp { op: BinOp, lhs: NodeHash, rhs: NodeHash, }, Fail(String), Handle { body: NodeHash, handlers: Vec<(String, NodeHash)>, }, If { cond: NodeHash, then_branch: NodeHash, else_branch: NodeHash, }, Step { binding: String, value: NodeHash, }, Function { name: String, type_params: Vec<String>, params: Vec<Param>, produces: Produces, requires: BTreeSet<Effect>, on_failure: Vec<String>, body: Vec<NodeHash>, result: NodeHash, }, Module { name: String, types: Vec<NodeHash>, functions: Vec<NodeHash>, }, RecordDef { name: String, fields: Vec<(String, Type)>, }, Record { type_name: String, fields: Vec<(String, NodeHash)>, }, Field { base: NodeHash, type_name: String, field: String, }, VariantDef { name: String, cases: Vec<(String, Vec<(String, Type)>)>, }, Variant { type_name: String, case: String, fields: Vec<(String, NodeHash)>, }, Match { scrutinee: NodeHash, type_name: String, arms: Vec<MatchArm>, },
}
Expand description

A stored AST node. Compound variants reference children by NodeHash.

Variants§

§

Lit(i64)

An integer literal. (A single unified numeric type is the language direction; the seed model only needs a concrete numeric leaf.)

§

FloatLit(u64)

An IEEE-754 double, stored as its bit pattern so the node stays Eq/hashable and content-addresses deterministically. The uniform i64 slot is these bits; only FloatOp/conversions reinterpret.

§

FloatOp

Arithmetic or comparison on two Floats. op is restricted to + - * / and == < <= > >= (no % != && || on Float).

Fields

§

IntToFloat(NodeHash)

NumberFloat.

§

FloatToInt(NodeHash)

FloatNumber: truncates toward zero; traps on NaN/overflow (a clean trap, not silent UB — like the bounds checks).

§

DecimalLit(i64)

A Decimal literal: the value pre-scaled by 10_000 (so 1.25 is 12500). Exact; no rounding at use.

§

DecimalOp

Arithmetic or comparison on two Decimals. + - are plain i64; * is (a*b)/10000, / is (a*10000)/b (rescaling). All six comparisons are exact. % && || are rejected by the checker.

Fields

§

IntToDecimal(NodeHash)

NumberDecimal (multiplies by 10_000).

§

DecimalToInt(NodeHash)

DecimalNumber (integer part; truncates toward zero).

§

DecimalRaw(NodeHash)

DecimalNumber: the raw scaled mantissa (the value ×10_000, Decimal’s documented representation). Identity at runtime; the seam that lets decimal_to_str be written in Cairn.

§

Bool(bool)

A boolean literal. Bool was previously only producible by a comparison; the literal makes Bool a first-class value the logical operators can stand on.

§

Not(NodeHash)

Logical negation of a Bool, yielding Bool. The one unary operator (Principle 9); &&/|| are the binary BinOps.

§

Str(String)

A UTF-8 string literal.

§

StrLen(NodeHash)

Length (in bytes) of a string. The first string operation; more follow with the stdlib.

§

StrLower(NodeHash)

ASCII-lowercase a string (AZaz, other bytes unchanged). The minimal primitive for case-insensitive matching — needed because some platforms (e.g. Cloudflare) lowercase HTTP header names, so the header/cookie lookup cannot be case-sensitive (design.md §9).

§

StrFromCode(NodeHash)

A one-byte string from a code point 0–255 (the low byte of the Number; the inverse of indexing a byte out). The minimal primitive for percent-decoding — added when a real HTML form (the shipped blog’s create) forced form_value to URL-decode %XX/+, which is otherwise inexpressible in pure Cairn (design.md §9; Principle 10 — a real need, not speculation).

§

StrConcat(NodeHash, NodeHash)

a ++ b — concatenate two strings.

§

StrSlice

Byte substring s[start .. start+len]. Bounds-checked: a negative index/length or start+len > len(s) traps (not silent UB), proven by out_of_bounds_list_get_and_str_slice_trap. Byte-indexed by design (decided, not a gap): a Cairn String is byte-addressable for predictable, AI-author-friendly indexing; codepoint-aware slicing is a stdlib concern, not a core operator (Principle 9). Slicing across a UTF-8 boundary therefore yields bytes the host renders lossily — the documented, intended semantics of a byte slice.

Fields

§start: NodeHash
§

StrEq(NodeHash, NodeHash)

Content equality of two strings, yielding Bool.

§

StrContains

Whether needle occurs in haystack, yielding Bool.

Fields

§haystack: NodeHash
§needle: NodeHash
§

StrStartsWith

Whether s begins with prefix, yielding Bool. With StrSlice/StrLen this is enough for prefix routing and path-parameter extraction (e.g. /customers/{id}).

Fields

§prefix: NodeHash
§

StrIndexOf

0-based byte index of the first occurrence of needle in haystack, or -1 if absent (an empty needle is at 0). Yields Number. With StrSlice this is enough to split a delimited string — e.g. parsing db_query rows into typed records.

Fields

§haystack: NodeHash
§needle: NodeHash
§

NumberToStr(NodeHash)

Decimal rendering of a Number as a String (e.g. for HTML output). Correct over the full i64 range, including i64::MIN (rendered in the non-positive domain — no magnitude overflow).

§

StrToNumber(NodeHash)

Parse a String to a Number, leniently: an optional leading - then the leading decimal digits; a non-numeric/empty string yields 0. The unchecked fast path (cf. StrToNumberOpt).

§

StrToNumberOpt(NodeHash)

Checked parse: Some(n) only if the whole string is a valid integer (optional - then ≥1 digits, nothing else), else None. The handle-able counterpart to StrToNumber, paralleling ListGet/ListTryGet.

§

Now

Read the clock (milliseconds). The first effectful primitive: it performs the Time effect and yields a Number at external confidence (the value comes from outside the program). Lowers to a host import; other effects follow the same pattern.

§

List(Vec<NodeHash>)

A non-empty list literal. Elements share a type T; the list’s type is List<T>. (Empty literals need a type annotation — unsupported in v0.3.)

§

ListEmpty

The empty List<elem>. The typed counterpart to a List literal, needed because the element type can’t be inferred with no elements. With ListCons this lets a recursive function build a list of runtime length.

Fields

§elem: Type
§

ListCons

Prepend head to tail (a List<T>), yielding a new List<T>. v0.3: an O(n) fresh-array copy — immutable, no structural sharing, consistent with the bump allocator’s documented simplicity.

Fields

§

OptionSome(NodeHash)

Some(value) — a present Option<T> where T is the value’s type. The typed result for operations that may have no answer.

§

OptionNone

None : Option<elem> — the absent case (element type can’t be inferred with no value, like ListEmpty).

Fields

§elem: Type
§

OptionElse

Eliminate an Option<T>: the contained value if Some, else default. Both arms share T, the expression’s type. This is the noise-free recovery path — no on_failure threading.

Fields

§default: NodeHash
§

OptionMatch

Case analysis over an Option<T>: bind the payload to some_bind in some_body, else evaluate none_body. Both bodies share a type (the expression’s type). Unlike OptionElse (value or default) this runs different logic per case — the construct that makes a returned Option usable for control flow.

Fields

§some_bind: String
§some_body: NodeHash
§none_body: NodeHash
§

ListTryGet

Checked indexing: Some(elem) if index is in bounds, else None. The handle-able counterpart to ListGet (which traps); neither pollutes signatures with a failure.

Fields

§index: NodeHash
§

ListLen(NodeHash)

Number of elements in a list.

§

ListGet

Element of a list at a (0-based Number) index. No runtime bounds check in v0.3 (a known simplification, like the bump allocator).

Fields

§index: NodeHash
§

Map(Vec<(NodeHash, NodeHash)>)

A non-empty map literal of key/value pairs. Keys share a type K, values a type V; the type is Map<K, V>.

§

MapGet

Value for a key (linear scan). Key equality is i64/identity — exact for Number keys, which is Map’s decided domain (Principle 9: one canonical form). A missing key yields 0; MapTryGet is the handle-able form. Structural keying of any type (incl. String) is not a second mechanism here — it is find over a List of key/value records (stdlib, first-class functions), which is structural for any K. Decided, not deferred: adding key-kind dispatch to Map would be the speculative generality Principle 10 forbids when find already covers it (see string_keyed_lookup_is_find_over_a_list).

Fields

§

MapTryGet

Checked lookup: Some(V) for the first matching key, else None — the handle-able counterpart to MapGet (which yields 0 on a miss, indistinguishable from a real 0). Same decided Number/identity key domain as MapGet.

Fields

§

MapLen(NodeHash)

Number of entries in a map.

§

Log(NodeHash)

Observe a value for diagnostics (the Log effect), passing it through unchanged (same type and confidence as the argument). Lowers to a host::log import.

§

Publish(NodeHash)

Announce that topic (a String) changed — the Live effect (design.md §10). The live runtime re-renders and pushes to every connection subscribed to that topic. Yields Number (0). Lowers to a host::publish import. Liveness is this, explicit and effect-typed — never an implicit default.

§

SetHeader

Emit an extra HTTP response header — the Resp effect. name and value are Strings (e.g. "Set-Cookie", "sid=abc; HttpOnly; Path=/"); the host buffers it per request and writes it after the standard headers. Yields Number (0), so it sequences in a step like publish. Lowers to a host::set_header import. Response headers are this, explicit and effect-typed — not a hidden Response field.

Fields

§value: NodeHash
§

Rand

Draw a random Number (the Rand effect), at external confidence (it comes from outside the program). Lowers to a host::rand import.

§

MutNew(NodeHash)

Allocate a mutable cell holding value (the Mut effect). Type is Cell<T> where T is the value’s type.

§

MutGet(NodeHash)

Read a mutable cell’s current value.

§

MutSet

Write value into a cell (the Mut effect); passes value through.

Fields

§value: NodeHash
§

DiskWrite

Write a String to a path (the Disk effect); returns the number of bytes written.

Fields

§content: NodeHash
§

DiskRead(NodeHash)

Read the file at a String path (the Disk effect), returning its contents as a String (host→wasm allocation). A missing file yields the empty string in v0.3.

§

NetGet(NodeHash)

HTTP(S) GET a String URL (the Net effect), returning the HTTP status as a Number (-1 on transport error). Backed by a real ureq + TLS client — no stub path exists (proven by real_net_get_returns_the_http_status).

§

DbQuery

Run a SQL statement (the Db effect), returning the result as a String at persisted confidence (read back from the system of record). params is a List<String> bound to the statement’s ? placeholders by the driver — the only query form, so user input never reaches SQL by concatenation (use an empty list for static SQL). Backed by real embedded SQLite only (rusqlite — in-memory by default, a file when a path is given). There is no canned/stub path: every query hits the engine (wasm::run_sql; the v0.3 removal of the old canned path is complete).

Fields

§params: NodeHash
§

Ref(String)

A reference to an in-scope binding, by name.

§

Call

A call: a callee function name plus argument nodes.

Fields

§func: String
§

FuncRef(String)

A named module function used as a first-class value. Its type is the function’s signature as a Fn. Anonymous lambdas with transitive closure capture are shipped (K2 — see Lambda/CallValue; the stdlib map/filter/fold and every app pass closures). FuncRef is the named-function value form; Lambda is the anonymous/closure form — both lower through the funcref table + call_indirect.

§

CallValue

Apply a function value to arguments. callee evaluates to a Fn; args are checked against its parameter types and its effects union into the caller. Lowers to call_indirect.

Fields

§callee: NodeHash
§

Lambda

An anonymous closure. params are its inputs (typed, like a function’s); body is a single result expression. Names it references that are neither its params nor module functions are captured by value from the enclosing scope at creation. Its type is a Fn; its body’s effects live in that Fn (a closure’s effects fire when it is called, not when it is made). v0.4: a single-expression body and no uncaught Fail (documented — write a named function and FuncRef it for step bodies or failures).

Fields

§params: Vec<Param>
§

Hole

A typed hole: an unfilled position carrying what it expects.

Fields

§expects: String
§

BinOp

A binary operation over two sub-expressions.

Fields

§

Fail(String)

Raise a typed failure, short-circuiting the reasoning chain. Its type is Never. The named variant must be covered by the enclosing function’s on_failure unless a Handle catches it.

§

Handle

Run body; if it raises one of the handled failure variants, evaluate that handler’s recover expression instead. A handled failure does not propagate. handlers maps a failure-variant name to its recovery expression (which yields the value, or itself fails).

Fields

§handlers: Vec<(String, NodeHash)>
§

If

A conditional expression. cond must be Bool; the two branches share a type, which is the expression’s type. There is no statement form — Cairn has expressions and reasoning-chain steps, not imperative control flow.

Fields

§then_branch: NodeHash
§else_branch: NodeHash
§

Step

A reasoning-chain step: binding = value.

Fields

§binding: String
§value: NodeHash
§

Function

A function: the full Section 4 contract plus an ordered body and a result expression.

Fields

§name: String
§type_params: Vec<String>

Declared generic type parameters (e.g. ["T"]). Empty = monomorphic.

§params: Vec<Param>
§produces: Produces
§requires: BTreeSet<Effect>
§on_failure: Vec<String>
§result: NodeHash
§

Module

A module: named type definitions and function definitions, referenced by hash. The unit a checker resolves calls and type names within.

Fields

§name: String
§types: Vec<NodeHash>
§functions: Vec<NodeHash>
§

RecordDef

A record (product) type definition: named fields, each with a type.

Fields

§name: String
§fields: Vec<(String, Type)>
§

Record

Construct a record value of a named record type.

Fields

§type_name: String
§fields: Vec<(String, NodeHash)>
§

Field

Access a field of a record value. type_name is the record type the base must have; it makes the node self-describing for type-directed lowering (the checker verifies it; the projection elides it).

Fields

§type_name: String
§field: String
§

VariantDef

A variant (sum) type definition: named cases, each with named payload fields (an empty payload is a nullary case).

Fields

§name: String
§cases: Vec<(String, Vec<(String, Type)>)>
§

Variant

Construct a value of a named variant type, in one of its cases.

Fields

§type_name: String
§case: String
§fields: Vec<(String, NodeHash)>
§

Match

Case analysis over a variant value. Must be exhaustive. type_name is the scrutinee’s variant type (self-describing for type-directed lowering; the checker verifies it, the projection elides it).

Fields

§scrutinee: NodeHash
§type_name: String

Implementations§

Source§

impl Node

Source

pub fn hash(&self) -> NodeHash

This node’s content hash. Because children are referenced by hash, this transitively covers the entire subtree (the Merkle property).

Trait Implementations§

Source§

impl Clone for Node

Source§

fn clone(&self) -> Node

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for Node

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<'de> Deserialize<'de> for Node

Source§

fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>
where __D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
Source§

impl PartialEq for Node

Source§

fn eq(&self, other: &Node) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 (const: unstable) · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
Source§

impl Serialize for Node

Source§

fn serialize<__S>(&self, __serializer: __S) -> Result<__S::Ok, __S::Error>
where __S: Serializer,

Serialize this value into the given Serde serializer. Read more
Source§

impl Eq for Node

Source§

impl StructuralPartialEq for Node

Auto Trait Implementations§

§

impl Freeze for Node

§

impl RefUnwindSafe for Node

§

impl Send for Node

§

impl Sync for Node

§

impl Unpin for Node

§

impl UnsafeUnpin for Node

§

impl UnwindSafe for Node

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<Q, K> Equivalent<K> for Q
where Q: Eq + ?Sized, K: Borrow<Q> + ?Sized,

Source§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
Source§

impl<Q, K> Equivalent<K> for Q
where Q: Eq + ?Sized, K: Borrow<Q> + ?Sized,

Source§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
Source§

impl<Q, K> Equivalent<K> for Q
where Q: Eq + ?Sized, K: Borrow<Q> + ?Sized,

Source§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
Source§

impl<Q, K> Equivalent<K> for Q
where Q: Eq + ?Sized, K: Borrow<Q> + ?Sized,

Source§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<T> Pointable for T

Source§

const ALIGN: usize

The alignment of pointer.
Source§

type Init = T

The type for initializers.
Source§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
Source§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
Source§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
Source§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> DeserializeOwned for T
where T: for<'de> Deserialize<'de>,