You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
@@ -616,28 +616,126 @@ Using this implementation of the Y-combinator instead of the source level define
616
616
The [sourcecode for this section can be found here](https://github.com/thma/lambda-ski/blob/main/src/LambdaToSKI.hs).
617
617
618
618
619
+
## Evaluating Combinator Expressions as Haskell Functions
620
+
621
+
The graph-reduction machine described above is not the only evaluation backend in this project.
622
+
Two further evaluators follow a different philosophy: instead of allocating terms into a mutable graph and rewriting it in place, they compile source expressions into an intermediate representation and then execute that representation by mapping it directly to Haskell functions.
623
+
Both are implemented in the `src/` tree and are exercised by the same benchmark programs (factorial, fibonacci, Ackermann, tak).
624
+
625
+
### The HhiReducer
626
+
627
+
[`src/HhiReducer.hs`](src/HhiReducer.hs) operates on combinator terms (`CL` / `CExpr`).
628
+
The pipeline has three stages:
629
+
630
+
1.**Compile** — a λ-expression is bracket-abstracted to a `CL` combinator tree (by `Kiselyov.compileEta` / `compileBulk`).
631
+
2.**Translate** — `translate :: CL -> CExpr` turns the combinator tree into a `CExpr` value.
|**Typing**| Untyped; bad applications fail at runtime via pattern-match (`can't handle`) | Strongly typed; ill-typed compositions rejected by GHC |
713
+
|**Source input**|`CL` combinator tree produced by bracket abstraction |`Expr` λ-term compiled directly without prior bracket abstraction |
714
+
|**Compilation strategy**| Structural translation of combinator application tree | Mixed NBE (for ordinary terms) + direct `Fix`-node construction (for `y`-recursion) |
715
+
|**Application model**|`(!) :: CExpr -> CExpr -> CExpr` — pattern-matches on `CFun f` and applies it |`interp Apply = uncurry interp` — functions are first-class `CatExpr` values |
716
+
|**Booleans**| Scott-encoded: `TRUE = A (= λt e. e)`, `FALSE = K (= λt e. t)`; comparisons return combinator values | Primitive `T`, `F` constructors; conditionals via `IfVal :: CatExpr (Bool,(a,a)) a`|
717
+
|**Branching**| Continuation-passing via Scott-encoding: `if c t e` → `c t e` reduces by combinator rule |`interp IfVal = \(test,(t,e)) -> if test then t else e` — native Haskell `if`|
718
+
|**Arithmetic**|`arith op = CFun \(CInt a) -> CFun \(CInt b) -> CInt (op a b)` wraps native operators as `CFun`|`Add`, `Sub`, `Mul` GADT constructors; `interp Add = addC` via `NumCat` type class |
719
+
|**Recursion**|`Y --> CFun (\(CFun f) -> fix f)` in `primitives`|`Fix` constructor in `CatExpr`; `interp (Fix step) = let rec = Fix step in interp step (rec, a)`|
720
+
|**Structure of terms**| Binary application trees (left-nested `CApp` chains, like the combinator spine) | Cartesian products and projections (`Fst`, `Snd`, `Dup`, `Par`) carry the argument structure |
721
+
|**Normal form**| The final `CInt` (or partial `CFun`) reached after all `(!)` applications are exhausted | The value of type `b` returned when the Haskell function `interp morph` is applied to its input |
722
+
|**Failure mode**|`error` via explicit `can't handle` match or arithmetic pattern failure |`error` in `compileNumExpr` for unsupported terms; type-level safety otherwise |
723
+
724
+
In short: HhiReducer is an *operational* evaluator — it treats programs as trees of combinator applications and executes them by a chain of function lookups and applications.
725
+
The CCC pipeline is a *denotational* evaluator — it gives each morphism a direct mathematical meaning as a function in the `(->)` category and computes by interpreting that meaning.
726
+
Both reach the same results, but the CCC route preserves more structure explicitly in the intermediate representation and leverages the Haskell type system to rule out malformed programs.
727
+
728
+
---
729
+
619
730
## Next steps
620
731
621
732
Here are some ideas for possible future extensions and improvements.
622
733
623
734
- Extending this very basic setup to a fully working pogramming environment with a REPL
624
735
- Implement direct and mutual recursion (i.e. `letrec`) for global function definitions
625
736
- experimemnt with different bracket abstraction algorithms to improve object code size and execution time.
626
-
- Implement bracket abstraction from λ-expressions to [closed cartesian categories](https://thma.github.io/posts/2021-04-04-Lambda-Calculus-Combinatory-Logic-and-Cartesian-Closed-Categories.html) and extend the graph-reduction to also cover the resulting combinators `apply` and `(△)`.
737
+
627
738
- extend the language to include lists, maybe even provide it with a LISPKIT frontend.
628
739
- Add support for implicit and explicit parallelism of the graph-reduction engine.
629
740
(implicit parallelism for strict operations, and an explicit `P`-combinator)
0 commit comments