I'm trying to learn lambda calculus and Scheme Lisp. The tutorial on lambda calculus can be found here http://www.inf.fu-berlin.de/lehre/WS03/alpi/lambda.pdf.
The problem I'm facing is I don't know how to properly implement iteration.
(define (Y y) (((lambda (x) (y (x x))) (lambda (x) (y (x x))))))
(define (sum r n) ((is_zero n) n0 (n succ (r (pred n)))))
(display ((Y sum) n5))
I always get this error:
Aborting!: maximum recursion depth exceeded
I know the problem is about the evaluation order: the scheme interprets (Y sum)
first, which results in infinite recursion:
((Y sum) n5) -> (sum (Y sum) n5) -> ((sum (sum (Y sum))) n5) -> .... (infinite recursion)
but I want
((Y sum) n5) -> ((sum (Y sum) n5) -> (n5 succ ((Y sum) n4)) -> .... (finite recursion)
How can I solve this problem? thanks.
The standard way to delay a computation is by eta-expansion:
Thus
and evaluating
(sum (lambda (z) ((x x) z)))
just uses the lambda-function which contains the self-application, but doesn't invoke it yet.The expansion will get to the point
and only at that point will the self-application be performed.
Thus,
(YC sum)
=(sum (lambda (z) ((YC sum) z)))
, instead of the diverging (under the applicative order of evaluation)(Y sum)
=(sum (Y sum))
.