Posts
All the articles I've posted.
LETDEP: Dependency-Ordered Binding Semantics for let Expressions
LETDEP gives multiple-binding let expressions dependency-ordered binding semantics: initializer dependencies determine the evaluation order, allowing forward references while rejecting duplicate names and cyclic bindings.
LETSEQ: Sequential Binding Semantics for let Expressions
LETSEQ gives multiple-binding let expressions sequential binding semantics: bindings are evaluated in source order, with each new binding becoming available to the ones that follow it.
LETPAR: Parallel Binding Semantics for let Expressions
LETPAR gives multiple-binding let expressions parallel binding semantics: every initializer is evaluated in the incoming environment, so sibling bindings cannot see one another.
Multiple-Binding let Expressions - Syntax Before Semantics
Extend LET so a single let expression can contain multiple bindings, updating the grammar, AST, and parser before deciding what those bindings mean.
LET: Introducing Local Bindings and Scope
LET extends VAR with let expressions, allowing programs to introduce local bindings and showing how environments determine their scope and support shadowing.
VAR: Variables and Environments
VAR extends IF with variable expressions and environments, making evaluation depend on context as variable names are looked up in the current environment.
IF: Conditional Expressions and Selective Evaluation
IF extends ZERO with conditional expressions, using Boolean conditions to choose which of two branches to evaluate while leaving the other unevaluated.
Make it a Syntax Error
See how grammar and AST design in a tiny Elm interpreter can turn runtime type errors into syntax errors, simplify evaluation, and connect to GADTs.
ZERO: Boolean Values and Runtime Type Errors
ZERO extends DIFF with the zero? predicate and Boolean values, then introduces runtime type errors for expressions that use values of the wrong type.
Simplifying Whitespace with Lexeme Parsers in Elm
Learn how lexeme parsers simplify whitespace handling in elm/parser by consuming trailing whitespace and keeping parsers close to the grammar.
Why Recursive Elm Parsers Need Parser.lazy
Learn why recursive Elm parsers create cyclic definitions, how Parser.lazy breaks the cycle, and when recursive parsers do and don't need it.
DIFF: When Expressions Contain Expressions
DIFF extends CONST with difference expressions whose operands are themselves expressions, revealing the same recursive structure in the grammar, AST, parser, and evaluator.
Setting Up a Reproducible Elm Interpreter Project with Nix
Set up a reproducible Elm interpreter project with a Nix flake, Elm tooling, helper commands, source and test structure, and grammar documentation.
Testing an Elm Interpreter with elm-test
Learn how to test an Elm interpreter with elm-test at the lexer, parser, and interpreter boundaries, then extract a reusable testValue helper.
CONST: From Source Text to Value
CONST is a tiny Elm interpreter for non-negative integer constants, showing the path from source text through an AST to an evaluated value.