;; compute the max of a list of integers
(define Y
(lambda (w)
((lambda (f)
(f f))
(lambda (f)
(w (lambda (x)
((f f) x)))))))
((Y
(lambda (max)
(lambda (l)
(cond ((null? l) -1)
((> (car l) (max (cdr l))) (car l))
(else (max (cdr l)))))))
'(1 2 3 4 5))
I wish to understand this construction. Can somebody give a clear and simple explanation for this code?
For example, supposing that I forget the formula of Y. How can I remember it , and reproduce it long after I work with it ?
Here's some related answers (by me):
Basically, with Y defined as
λr.(λh.h h) (λg.r (λx.(g g) x))
, an applicationY r
reduces asSo
r
must expect two arguments - first representing the recursive function to be called, and second - an actual argument:so that
(Y r) x
reduces asThe definiton
f = (λx.(g g) x)
means, whenf y
is called,(g g) y
will be called, at which pointg
will be self-applied,r
"pulled" from insideg
and the result of(r f)
called withy
argument. I.e. any call(f y)
in the body of lambda expression resulting from(r f)
application, is translated back to(r f) y
i.e. invocation of same body with a new argumenty
.The important implementational detail is whether it is the same function body, or its copy, but the semantics are the same - we are able to enter the same function body with a new argument value.
The essence of Y combinator is replication through reference and self-application: we refer to the same thing through same name, twice; and thus we arrange for it to receive itself as an argument.
When there's no referencing, as in pure lambda calculus, and parameters receive textual copies of arguments - i.e. reduction is done by textual rewriting - this still works, because same copies get replicated and passed around, being fed as argument to self so it is available on the next iteration, if need be.
But it is much more efficient when shared referencing is available (all uses of same name refer to same thing). Under environment model of evaluation creation of self-referential function is simple as
In fact the definition in your answer is that of applicative-order Y combinator. With normal-order, eta-reduction can be applied without causing infinite looping, to get
Ynorm = (λw.(λh.h h) (λg.w (g g)))
which is canonically written asindeed