From aeffe6480486f1bc0efc417eeb294f0386250dbd Mon Sep 17 00:00:00 2001 From: "M.V. Hutz" Date: Fri, 16 Jan 2026 18:56:03 -0500 Subject: [PATCH] fix: update main and tests for new Reducer API Update call sites to match the new Reducer interface where the expression is passed to the constructor and Reduce() takes no arguments. --- cmd/lambda/lambda.go | 6 +++--- cmd/lambda/lambda_test.go | 4 ++-- pkg/lambda/reducer.go | 37 +++++++++++++++++-------------------- pkg/reducer/reducer.go | 2 +- 4 files changed, 23 insertions(+), 26 deletions(-) diff --git a/cmd/lambda/lambda.go b/cmd/lambda/lambda.go index 3d8570f..999e722 100644 --- a/cmd/lambda/lambda.go +++ b/cmd/lambda/lambda.go @@ -33,8 +33,8 @@ func main() { compiled := convert.SaccharineToLambda(ast) logger.Info("compiled λ expression", "tree", compiled.String()) - // Create reducer. - reducer := lambda.NewNormalOrderReducer() + // Create reducer with the compiled expression. + reducer := lambda.NewNormalOrderReducer(compiled) // If the user selected to track CPU performance, attach a profiler. if options.Profile != "" { @@ -58,7 +58,7 @@ func main() { } // Run reduction. - reducer.Reduce(compiled) + reducer.Reduce() // Return the final reduced result. result := reducer.Expression().String() diff --git a/cmd/lambda/lambda_test.go b/cmd/lambda/lambda_test.go index 3855fc5..73bdb85 100644 --- a/cmd/lambda/lambda_test.go +++ b/cmd/lambda/lambda_test.go @@ -30,8 +30,8 @@ func runSample(samplePath string) (string, error) { compiled := convert.SaccharineToLambda(ast) // Create and run the reducer. - reducer := lambda.NewNormalOrderReducer() - reducer.Reduce(compiled) + reducer := lambda.NewNormalOrderReducer(compiled) + reducer.Reduce() return reducer.Expression().String() + "\n", nil } diff --git a/pkg/lambda/reducer.go b/pkg/lambda/reducer.go index 2fe0d80..4c5ea19 100644 --- a/pkg/lambda/reducer.go +++ b/pkg/lambda/reducer.go @@ -6,20 +6,18 @@ import ( "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 { emitter.BaseEmitter[reducer.Event] - expression expr.Expression + expression Expression } // NewNormalOrderReducer creates a new normal order reducer. -func NewNormalOrderReducer() *NormalOrderReducer { +func NewNormalOrderReducer(expression Expression) *NormalOrderReducer { return &NormalOrderReducer{ BaseEmitter: *emitter.New[reducer.Event](), + expression: expression, } } @@ -30,23 +28,22 @@ func (r *NormalOrderReducer) Expression() expr.Expression { // 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) expr.Expression { - r.expression = e +func (r *NormalOrderReducer) Reduce() { + r.Emit(reducer.StartEvent) + it := NewIterator(&r.expression) - lambdaExpr, ok := e.(Expression) - if !ok { - return e + for !it.Done() { + if fn, arg, ok := IsViable(it.Current()); !ok { + it.Next() + } else { + it.Swap(Substitute(fn.body, fn.parameter, arg)) + r.Emit(reducer.StepEvent) + + if _, _, ok := IsViable(it.Parent()); ok { + it.Back() + } + } } - r.Emit(reducer.StartEvent) - - ReduceAll(&lambdaExpr, func() { - r.expression = lambdaExpr - r.Emit(reducer.StepEvent) - }) - - r.expression = lambdaExpr r.Emit(reducer.StopEvent) - - return lambdaExpr } diff --git a/pkg/reducer/reducer.go b/pkg/reducer/reducer.go index ec2d02a..114691c 100644 --- a/pkg/reducer/reducer.go +++ b/pkg/reducer/reducer.go @@ -20,7 +20,7 @@ type Reducer interface { // Emits StartEvent before reduction, StepEvent after each step, and // StopEvent after completion. // Returns the final reduced expression. - Reduce(e expr.Expression) expr.Expression + Reduce() // Expression returns the current expression state. Expression() expr.Expression