What It Is
The Interpreter pattern evaluates sentences in a small language by building a tree of expression objects — each node knows how to interpret itself. Numbers interpret to themselves; an addition node interprets its two sides and adds them.
It fits small languages: filters, formulas, simple rules. Real languages deserve real parser tools.
Example: A Tiny Calculator
The input 3 + 4 - 2 becomes a tree of Number, Add and Subtract nodes. One call to Interpret() on the root evaluates the whole expression.
Every node interprets itself
parse builds the tree left to right; Interpret() walks it. Supporting * would be one new node type — the existing ones stay untouched.
Output: Go program and captured output
package main
import (
"fmt"
"strconv"
"strings"
)
// Every node knows how to interpret itself.
type Expression interface {
Interpret() int
}
type Number struct{ value int }
func (n Number) Interpret() int { return n.value }
type Add struct{ left, right Expression }
func (a Add) Interpret() int { return a.left.Interpret() + a.right.Interpret() }
type Subtract struct{ left, right Expression }
func (s Subtract) Interpret() int { return s.left.Interpret() - s.right.Interpret() }
func parse(input string) Expression {
parts := strings.Fields(input)
n, _ := strconv.Atoi(parts[0])
var expr Expression = Number{n}
for i := 1; i < len(parts); i += 2 {
n, _ := strconv.Atoi(parts[i+1])
if parts[i] == "+" {
expr = Add{expr, Number{n}}
} else {
expr = Subtract{expr, Number{n}}
}
}
return expr
}
func main() {
input := "3 + 4 - 2"
fmt.Println(input, "=", parse(input).Interpret())
}
When to Use It
Use it when users or configs express logic in a small language of your design: search filters, pricing formulas, validation rules.
Skip it when the "language" is three fixed options (use a switch) — or a real language (use a parser generator or an existing engine).
Pros and Cons
Pros: the grammar maps one-to-one onto small types; new operations are new node types; expression trees can be built, checked and reused.
Cons: grows painful as the grammar grows; parsing itself still has to be written; performance is modest compared to compiled logic.