eru
eru is a simple and rather dumb λ term reducer.
You can get the source code here.
Syntax
| item | description | where |
|---|---|---|
|
|
a λ abstraction |
|
|
|
a function application |
|
|
|
reduce |
|
|
|
toplevel environment binding of a λ abstraction or a value to a name |
|
A program is a mixture of all of those. The value bound to the name `output' is reduced and printed to the standard output.
You can use the -v (verbose) flag to show the number of passes used.
You can use the -vv (very verbose) flag to show every single step of reduction.
Files in lib/ are compiled into the `eru' binary, and can be later included in your program with:
.include basename.l so, lib/cons.l would be included with
.include cons.l
the .include directive will try to include a file from your local file system, when a given filename is not compiled in.
Examples
-
bazinga
bazinga ← λx.λy.x output ← ((bazinga mrow) boo)usage:
$ ./eru -v t/bazinga.l Reduced in 5 passes, 4 substitutions. 144 bytes allocated. 7 symbols used. mrow -
self-referencing factorial using Y combinator
.include comb.l succ ← λn.λf.λx.(f ((n f) x)) pred ← λn.λf.λx.(((n λg.λh.(h (g f))) λ_.x) I) 0 ← λf.λx.x 1 ← (succ 0) 4 ← (succ (succ (succ 1))) zero? ← λn.((n λx.false) true) * ← λm.λn.((m (+ n)) 0) + ← λm.λn.((m succ) n) fac ← (Y λf.λn.(((zero? n) 1) ((* n) (f (pred n))))) output ← (fac 4)usage:
$ ./eru -v t/fac.l Reduced in 298 passes, 10264 substitutions. 83394720 bytes allocated. 32 symbols used. λf.λx.(f (f (f (f (f (f (f (f (f (f (f (f (f (f (f (f (f (f (f (f (f (f (f (f x)))))))))))))))))))))))) -
almost a iota (featuring a stupid hack to overcome the naivity of the reducer)
.include eru.l rev ← (Y λrev.λl.(((null? (cdr l)) ((cons (car l)) nil)) ((append' (rev (cdr l))) (car l)))) append' ← (Y λappend'.λl.λel.(((null? l) ((cons el) nil)) ((cons (car l)) ((append' (cdr l)) el)))) riota ← (Y λriota.λx.(((zero? x) nil) ((cons x) (riota (pred x))))) output ← (car (rev #(riota 3))) ;; ^- here's the hack ;; it evaluates the riota in-place there when parsing the source ;; because (rev)-ing at the same time makes the reducer go boomusage:
$ ./eru t/iota.l λf.λx.(f x)