Expression Hierarchy#

At the core of EQL is a rich hierarchy of symbolic expressions. Every logical operation, variable, and aggregator inherits from SymbolicExpression.

The Root: SymbolicExpression#

The SymbolicExpression class defines the interface and life-cycle for all symbolic nodes in the execution graph.

Key Responsibilities:#

  • _evaluate__: The internal method that subclasses must implement to yield OperationResult objects.

  • Parent/Child Management: Expressions maintain references to their parents and children to build a rooted DAG.

  • Public API: Methods like evaluate, tolist, and first that trigger graph execution.

Arity-based Specialization#

To simplify implementation, EQL provides base classes for different numbers of children:

Hint

When extending EQL, choose the base class that matches your operator’s arity. This handles the child field management for you automatically.

Behavioral Mixins#

EQL uses mixins to define common behaviors across different parts of the hierarchy:

1. TruthValueOperator#

Used for expressions that contribute to the truth value of a condition. Parents of these nodes only request evaluation when their truth value is relevant (e.g., short-circuiting logic).

2. DerivedExpression#

Represents operations that transform the result stream (like sorting or quantification) without owning the primary data.

3. Selectable#

A specialized expression that can be “selected” in a query’s result set. Variables and aggregators are selectables.

Note

The hierarchy is designed to enable deeply nested expressions having subqueries as children of parent queries.

Warning

Directly overriding _evaluate_ (single underscore) is dangerous. Always override _evaluate__ (double underscore) to ensure that parent/child tracking and result processing are handled correctly.

API Reference#