ddn.df.expr

The typed, inspectable expression layer of ddn.df (ADR-2026-10-24-16, amended 2026-10-29): composable column computations as a tagged-struct AST - column references, literals, unary/binary operators, aggregations, casts, conditionals, aliases and window (over) wrappers - evaluated against a DataFrame by a tree interpreter that reuses the existing eager kernels, including the scalar-literal fast dispatch. No new computation paths: results are bitwise-identical to the eager chains.

Structure is inspectable without evaluating data: kind, children, dependencies and resolve(schema) expose the tree, its column dependencies and its dtype/nullability/cardinality metadata. Construction is schema-free and non-throwing for unknown columns (they surface at collection); structural misuse - aggregations over computed expressions, aggregates mixed with row expressions - is rejected at construction.

Aggregations (col("v").sum() and friends) evaluate standalone as global length-1 reductions through the Series aggregation kernels; wrapped in .over(keys) they dispatch to the partitioned-aggregate kernels (dtype-preserving). A bare col("v").over(keys) keeps the historical per-partition first-row scatter with FLOAT64 output - the compatibility form. The list collect aggregation has no expression form (it needs the grouping context).

Types 7

The kind of one expression AST node.

COLUMN_REFa named input column
LITERALa length-1 constant
UNARYprefix `-` or `!`
BINARYarithmetic, comparison or logic operator
AGGan aggregation over a direct column reference
CASTan explicit dtype cast
WHENa mask/then/otherwise conditional
ALIASa rename
OVERa partitioned window wrapper

The value space of a literal node.

BOOL
LONG
DOUBLE
STRING

One literal value: the kind discriminator plus the payload slots (only the active kind's slot is meaningful).

Fields
bool boolValue
long longValue
double doubleValue
string stringValue

The row cardinality an expression produces: a broadcastable length-1 result (SCALAR), one value per input row (ROW), a global length-1 reduction (AGGREGATE) or a partitioned aggregate scattered back to input rows (WINDOW).

SCALAR
ROW
AGGREGATE
WINDOW

One named column of an input schema: a name and dtype pair.

Fields
string name
DataType dtype
structExprInfo

The resolved metadata of one expression against an input schema.

Fields
DataType dtype
bool nullable
ExprCardinality cardinality
string[] dependencies
structExpr

A typed, deferred column computation: an inspectable AST. Constructed with col(name) or lit(value), composed with D's operators (`*`, `+`, `>`, ...) and comparison/logic methods (.gt, .and, ...), aggregated (.sum(), .quantile(q), ...), cast (.castTo), renamed (.rename) and wrapped in windows (.over), then evaluated against a frame - reusing the eager kernels, no new computation paths. The output name defaults to a rendering of the tree.

Fields
string labelThe expression's output name (rendered from the tree shape).
private ExprKind _kind
private Expr[] _children
private string _name
private LiteralValue _literal
private string _op
private AggKind _agg
private double _aggParam
private DataType _castTarget
private bool _castStrict
private string[] _keys
Methods
ExprKind kind() const @safe pure nothrowThe node kind.
Expr[] children()The child nodes (a copy; leaves return an empty array).
bool isWindow() const @safe pure nothrowWhether the tree contains an `over` window (blocking for streaming; see ADR-2026-10-24-18).
bool isAggregate() const @safe pure nothrowWhether the tree holds an aggregation outside an `over` wrapper: a length-1 reduction. Row-wise plan operations reject such expressions, and they may only combine with scalars or other aggregates.
string[] dependencies() @safe pureThe input columns the expression references (unique, in first appearance order), without evaluating any data. `over` keys are dependencies of their own.
ExprInfo resolve(DataFrame df) @safeResolves the expression against a frame's schema (column names and dtypes only; no data is touched).
ExprInfo resolve(scope ColumnSchema[] schema) @safeResolves the expression against an explicit input schema: the output dtype, conservative nullability, row cardinality and column dependencies. This is the inspection entry the plan layer and the op...
Series evaluate(DataFrame df) @trustedEvaluates the expression against a frame: a tree walk that dispatches each node to the eager kernels.
Expr gt(Expr other) @safe
Expr ge(Expr other) @safe
Expr lt(Expr other) @safe
Expr le(Expr other) @safe
Expr eq(Expr other) @safe
Expr ne(Expr other) @safe
Expr and(Expr other) @safe
Expr or(Expr other) @safe
Expr not() @safe
Expr opBinary(string op : "*")(Expr rhs) @safe
Expr opBinary(string op : "/")(Expr rhs) @safe
Expr opBinary(string op : "+")(Expr rhs) @safe
Expr opBinary(string op : "-")(Expr rhs) @safe
Expr opBinary(string op : "%")(Expr rhs) @safe
Expr opUnary(string op : "-")() @safe
Expr opBinary(string op : "*")(double rhs) @safe
Expr opBinary(string op : "*")(long rhs) @safe
Expr opBinary(string op : "+")(double rhs) @safe
Expr opBinary(string op : "+")(long rhs) @safe
Expr opBinary(string op : "-")(double rhs) @safe
Expr opBinary(string op : "-")(long rhs) @safe
Expr opBinary(string op : "/")(double rhs) @safe
Expr opBinary(string op : "/")(long rhs) @safe
Expr rename(string name) @safeRenames the output (an alias node; evaluation renames the child's result).
Expr castTo(DataType target, bool strict = true) @safeCasts the output to a target dtype (the eager `castTo`: strict by default; out-of-range and unsupported casts throw at evaluation).
Expr over(string[] keys...) @safePartitions the frame by keys and evaluates the expression per partition, scattering each partition's result back to every input row of that partition (the `over` semantics of ADR-2026-10-24-17). Th...
Expr when(Expr a, Expr b) @safeSelects between two branches by this BOOLEAN expression (the eager `when` kernel: promoted branches; length-1 operands broadcast to the common height at evaluation).
string outputName() @safe pure nothrowThe column name evaluation produces for this expression (the kernels' naming rule): literals are `"lit"`, column references carry their column name, unary/cast results and when branches carry their...
bool aggSpec(out AggSpec spec) @safe pure nothrowConverts this expression (through alias chains) to the eager aggregation specification it maps to: the aggregation's kind, parameter and column, with the outermost alias label as the output name. T...
Expr sum() @safeThe sum in its promoted dtype.
Expr count() @safeThe non-null count (UINT32).
Expr mean() @safeThe arithmetic mean (FLOAT64; FLOAT32 for FLOAT32 columns).
Expr min() @safeThe dtype-preserving minimum (total order on floats).
Expr max() @safeThe dtype-preserving maximum (total order on floats).
Expr first() @safeThe first element (null when the column is empty or starts null).
Expr last() @safeThe last element (null when the column is empty or ends null).
Expr product() @safeThe product in the sum's promoted dtype (identity 1).
Expr median() @safeThe median (the 0.5 quantile; FLOAT64).
Expr quantile(double q) @safeThe linear-interpolation quantile (FLOAT64).
Expr std(size_t ddof = 1) @safeThe sample standard deviation (FLOAT64).
Expr variance(size_t ddof = 1) @safeThe sample variance (FLOAT64).
private Expr aggNode(AggKind kind, string name, double param = double.init) @safe
private Series oneSlot(string agg)(Series s)
private void resolveNode(scope ColumnSchema[] schema, ref ExprInfo info) @safe
private void collectDeps(ref string[] deps) const @safe pure
bool isTotal() @safe pure nothrowWhether the expression is provably total: direct column references and literals only. These produce the same values (or the same absence) on any row subset, so plan rewrites may move row-dependent ...
bool isColumnRefOf(string name) @safe pure nothrowWhether this expression is the identity reference of `name`.
private bool isScalar() const @safe pure nothrow

Functions 23

fnbool exprEq(Expr a, Expr b) @safe pure nothrowStructural equality of two expressions: same shape, same payload and same labels, recursively over the children. Deterministic trees built the same way compare equal; the comparison is exact (a NaN...
fnsize_t columnRefCount(Expr e, string name) @safe pure nothrowThe number of direct column references to `name` in the tree - the positions an inline substitution would replace. `over` partition keys reference columns by name without a reference node and are N...
fnbool overKeyRef(Expr e, string name) @safe pure nothrowWhether any `over` node in the tree partitions by `name`: such a key reads the materialised column and cannot take an inlined expression in its place, so fusion rules must stand down.
fnExpr substRef(Expr e, string name, Expr repl) @safeReplaces every direct column reference to `name` with `repl`, rebuilding the surrounding nodes through the same construction paths a hand-written tree takes (labels included; the replacement is ins...
private fnExpr binOp(string op, Expr l, Expr r) @safe
private fnSeries evalBinary(string op, Series l, Series r)
private fnSeries scalarColumnBinary(string op, Series scalar, Series column, bool scalarOnLeft, out bool handled)
private fnSeries scalarTypedBinary(T)(string op, Series scalar, Series column, bool scalarOnLeft, ref bool handled)
private fnSeries overExpr(DataFrame df, Expr inner, string[] keys, string label) @trustedEvaluates an expression per partition and scatters back to input rows (the bare-expression `over` implementation). Each partition's rows form a sub-frame; the expression evaluates on it; the first ...
fnExpr col(string name) @safeCreates a column-reference expression: evaluates to the named column's Series against a frame.
fnExpr lit(double v) @safeCreates a FLOAT64 literal expression (broadcast on evaluation).
fnExpr lit(long v) @safeDitto, INT64.
fnExpr lit(string v) @safeDitto, STRING.
fnExpr lit(bool v) @safeDitto, BOOLEAN.
private fnbool columnRefName(in Expr e, out string name) @safe pure nothrow
private fnbool aggPayload(in Expr e, out AggKind kind, out double param, out string column) @safe pure nothrow
private fnstring aggOverName(AggKind agg) @safe pure nothrow
private fnvoid aggInfo(AggKind agg, DataType d, ref ExprInfo info) @safe pure
private fnDataType schemaLookup(scope ColumnSchema[] schema, string name) @safe pure
private fnvoid addDep(ref string[] deps, string name) @safe pure
private fnsize_t max3(size_t a, size_t b, size_t c) @safe pure nothrow
private fnSeries broadcastTo(Series s, size_t n) @trusted
private fnvoid enforce(bool condition, string message) @safe