Skip to content

Commit

Permalink
Y-combinator.
Browse files Browse the repository at this point in the history
  • Loading branch information
Baris Aktemur committed Dec 3, 2016
1 parent 5ef5b3c commit 063d9fc
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 0 deletions.
35 changes: 35 additions & 0 deletions Lambda/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -111,3 +111,38 @@ Booleans, "if", and "isZero" predicate:
- : string = "(\\f.(\\x.(f (f (f (f x))))))"
```

Recursion, using fix-point calculation via a Y-combinator.
Below, we are calculation 3! and 4!.

```ocaml
# str(run "(Y (\fact.\m.if (isZero m)
one
(mult m (fact (pred m))))
) three");;
- : string = "(\\f.(\\x.(f (f (f (f (f (f x))))))))"
# str(run "(Y (\fact.\m.if (isZero m)
one
(mult m (fact (pred m))))
) four");;
- : string =
"(\\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))))))))))))))))))))))))))"
```

Note that the programs below are pure lambda terms;
"if", "pred", "mult" and other names with special meanings are
just syntactic convenience. They are converted to plain lambda terms by the parser.
E.g:

```ocaml
# str(parse "(Y (\fact.\m.if (isZero m)
one
(mult m (fact (pred m))))
) four");;
- : string =
"(((\\h.((\\x.(\\a.((h (x x)) a))) (\\x.(\\a.((h (x x)) a)))))
(\\fact.(\\m.((((\\cond.(\\then.(\\else.((cond then) else))))
((\\n.((n (\\x.(\\a.(\\b.b)))) (\\a.(\\b.a)))) m)) (\\f.(\\x.(f x))))
(((\\m.(\\n.(\\f.(\\x.((m (n f)) x))))) m)
(fact ((\\n.(\\f.(\\x.(((n (\\g.(\\h.(h (g f))))) (\\u.x)) (\\u.u))))) m)))))))
(\\f.(\\x.(f (f (f (f x)))))))"
```
4 changes: 4 additions & 0 deletions Lambda/grammar.mly
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
%token SUCC ADD
%token MULT PRED
%token IF TRUE FALSE ISZERO
%token YCOMB

%start main
%type <expr> main
Expand Down Expand Up @@ -50,6 +51,9 @@ atomExpr:
| IF { Lambda("cond", Lambda("then", Lambda("else", App(App(Var "cond", Var "then"), Var "else")))) }
| ISZERO { Lambda("n", App(App(Var "n", Lambda("x", Lambda("a", Lambda("b", Var "b")))),
Lambda("a", Lambda("b", Var "a")))) }
/* Definition of Y-combinator taken from PLC, page 85. */
| YCOMB { Lambda("h", App(Lambda("x", Lambda("a", App(App(Var "h", App(Var "x", Var "x")), Var "a"))),
Lambda("x", Lambda("a", App(App(Var "h", App(Var "x", Var "x")), Var "a"))))) }
| LPAR expression RPAR { $2 }
;

Expand Down
1 change: 1 addition & 0 deletions Lambda/lexer.mll
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ let keyword s =
| "true" -> TRUE
| "false" -> FALSE
| "isZero" -> ISZERO
| "Y" -> YCOMB
| _ -> NAME s
}

Expand Down

0 comments on commit 063d9fc

Please sign in to comment.