August 2026 · Java SE 26 · DOP & SDD
Data-Oriented Programming in Java — Scientific Calculator REPL
Building a zero-dependency scientific calculator and interactive REPL in modern Java SE 26 using immutable records, sealed hierarchies, pattern matching, and Specification-Driven Development.
Beyond OOP Bloat: Data-Oriented Architecture
Traditional object-oriented domain models often couple state with behavior in complex mutable class hierarchies. Data-Oriented Programming (DOP) in modern Java takes the opposite approach: treating data as passive, shallowly immutable records and code as pure functions operating on data via pattern matching.
The Java DOP Scientific Calculator REPL demonstrates this paradigm in Java SE 26: a zero-dependency scientific calculation engine, AST parser, algebraic simplifier, and POSIX raw terminal UI built without third-party frameworks or mutable runtime state.
The Four Core DOP Principles
The calculator architecture adheres strictly to the four foundational principles of Data-Oriented Programming:
1. Model Data with Shallowly Immutable Records
Abstract Syntax Tree (AST) nodes, evaluation results, and terminal events are modeled as pure immutable records with zero behavioral methods:
public sealed interface Term permits
Term.Value, Term.Constant, Term.Addition,
Term.Subtraction, Term.Multiplication, Term.Division,
Term.Power, Term.UnaryMinus, Term.FunctionCall {
record Value(BigDecimal value) implements Term {}
record Constant(ConstantType type) implements Term {}
record Addition(Term left, Term right) implements Term {}
record Multiplication(Term left, Term right) implements Term {}
record FunctionCall(FunctionType function, Term argument) implements Term {}
}
2. Sealed Hierarchies for Algebraic Data Types
Sealed interfaces (Term, EvaluationResult, ReplCommand) enforce closed algebraic sets at compile time, guaranteeing that all possible AST variants are known to the compiler.
3. Exhaustive Pattern Matching with switch Expressions
Evaluation logic and command routing are isolated in pure functions using exhaustive pattern matching with record deconstruction without requiring default fallback branches:
public EvaluationResult evaluate(Term term, AngleMode mode) {
return switch (term) {
case Term.Value(BigDecimal v) -> new EvaluationResult.Success(new Term.Value(v));
case Term.Addition(Term l, Term r) -> evaluateBinary(l, r, BigDecimal::add, mode);
case Term.Multiplication(Term l, Term r) -> evaluateBinary(l, r, BigDecimal::multiply, mode);
case Term.Division(Term l, Term r) -> evaluateDivision(l, r, mode);
case Term.FunctionCall(FunctionType f, Term arg) -> evaluateFunction(f, arg, mode);
};
}
4. Pure Algebraic AST Simplification Pass
Before numerical evaluation, expressions pass through an algebraic transformer (AstSimplifier) executing constant folding and identity reductions (e.g. x * 0 -> 0, x + 0 -> x, x^1 -> x).
Specification-Driven Development (SDD)
This project was engineered from conception to production using the Specification-Driven Development (SDD) lifecycle with the Antigravity CLI and Specify (speckit). Features progressed through rigorous formal phases before code was written:
001-dop-calculator-repl: Core DOP AST, recursive-descent parser, arbitrary-precision decimal engine (128-bit IEEE 754), and REPL loop.002-repl-autocomplete: Low-level ANSI/VT100 key decoding, POSIX raw terminal control, and Tab autocompletion.004-improve-autocomplete&005-smart-autocomplete: Context-aware expression parsing and command parameter completions.006-code-clean-up: Concurrency modernization, structured formatting, and error logging.
The Repository
The complete zero-dependency Java SE 26 calculator, AST test suites, and terminal REPL are available on GitHub:
github.com/lazarius-borg/java_terminal_calculator
Requires Java SE 26+ and Apache Maven 3.9+.