refactor: extract Reducer interface and update engine to use abstractions

Introduce reducer.Reducer interface and update the engine to use abstract
expr.Expression and reducer.Reducer types, enabling pluggable reduction
strategies.

- Add pkg/reducer/reducer.go with Reducer interface.
- Add pkg/lambda/reducer.go with NormalOrderReducer implementation.
- Update engine to accept expr.Expression and reducer.Reducer.
- Update plugins to use expr.Expression directly (no pointer dereference).
- Update main and tests to pass reducer to engine.

Closes #30
This commit is contained in:
2026-01-16 18:40:17 -05:00
parent e0114c736d
commit a61809ad1d
7 changed files with 71 additions and 16 deletions

33
pkg/lambda/reducer.go Normal file
View File

@@ -0,0 +1,33 @@
package lambda
import (
"git.maximhutz.com/max/lambda/pkg/expr"
"git.maximhutz.com/max/lambda/pkg/reducer"
)
// Ensure NormalOrderReducer implements reducer.Reducer.
var _ reducer.Reducer = (*NormalOrderReducer)(nil)
// NormalOrderReducer implements normal order (leftmost-outermost) reduction
// for lambda calculus expressions.
type NormalOrderReducer struct{}
// NewNormalOrderReducer creates a new normal order reducer.
func NewNormalOrderReducer() *NormalOrderReducer {
return &NormalOrderReducer{}
}
// Reduce performs normal order reduction on a lambda expression.
// The expression must be a lambda.Expression; other types are returned unchanged.
func (r *NormalOrderReducer) Reduce(e expr.Expression, onStep func(expr.Expression)) expr.Expression {
lambdaExpr, ok := e.(Expression)
if !ok {
return e
}
ReduceAll(&lambdaExpr, func() {
onStep(lambdaExpr)
})
return lambdaExpr
}

15
pkg/reducer/reducer.go Normal file
View File

@@ -0,0 +1,15 @@
// Package reducer provides the abstract Reducer interface for all expression
// reduction strategies.
package reducer
import "git.maximhutz.com/max/lambda/pkg/expr"
// Reducer defines the interface for expression reduction strategies.
// Different evaluation modes (normal order, applicative order, SKI combinators,
// etc.) implement this interface with their own reduction logic.
type Reducer interface {
// Reduce performs all reduction steps on the expression, calling onStep
// after each reduction.
// Returns the final reduced expression.
Reduce(e expr.Expression, onStep func(expr.Expression)) expr.Expression
}