Step 1 of 3 · Reading · ~2 min
Short-Circuit Evaluation
Control Flow & Functions
Logical Operators (and, or)
and and or look like binary operators — left and right, left or right — but they cannot be implemented as ordinary Binary expressions, because ordinary binary expressions always evaluate both operands before combining them. Logical operators must short-circuit: false and expensiveCall() must never call expensiveCall().
Why they need their own AST node
If you evaluated both sides eagerly, you'd break not just performance but correctness — a guard like list != nil and list.first() would crash on a nil list, defeating the entire point of writing the guard. So logical expressions get their own node, separate from Binary:
Parse it at its own precedence level (or binds looser than and, which binds looser than equality), but structurally it looks just like parsing any other left-associative binary operator — the difference is entirely in evaluation, not parsing.
Evaluation returns a value, not a boolean
This is the detail learners most often get wrong: and/or in a Lox-like language don't coerce their result to true/false. They return whichever operand determined the outcome:
Trace through the required examples:
true and false→ lefttrueis truthy, so forandwe fall through and evaluate/returnright→false.false or true→ leftfalseis falsy, so we fall through and returnright→true.1 or 2→ left1is truthy,orshort-circuits and returns1directly —2is never evaluated.nil or "yes"→ leftnilis falsy, soorevaluates and returnsright→"yes".
Why this matters architecturally
This "return the deciding operand" behavior is what lets or double as a default-value idiom (config.timeout or 30) and what makes and useful as a guarded-access idiom — both extremely common patterns once you get to writing real programs in your language. It also means your truthiness rule (from the previous lesson) has to be applied consistently at every one of these decision points: _truthy is called on left, but the value returned is never coerced.
Edge cases to watch
- Nested logical expressions:
a or b and cmust respect precedence (andtighter thanor), so parse this asa or (b and c). - Short-circuiting must be visible through side effects: a test harness might check that a function passed as the right operand is never called when the left operand already determines the result.
Discussion
Ask a question, share an insight, or help someone who’s stuck.
Sign in to post a comment or reply.
Loading…