[plt-scheme] Applicative-order Y Combinator

From: Jos Koot (jos.koot at telefonica.net)
Date: Sun May 24 06:50:24 EDT 2009

Consider the term (λ (m) ((λ (f) (m (f f))) (λ (f) (m (f f))))). We shall abbreviate it as ‘Y’. Let ‹term› be an arbitrary lambda 
term without free occurrences of m and n. If it has, we can α-convert Y such that it does not contain any variable occurring free in 
‹term›. Now:

1       (Y ‹term›) =                                                                           Write Y in full.

2     ((λ (m) ((λ (f) (m (f f))) (λ (f) (m (f f))))) ‹term›) =                    Substitute ‹term› for m.

3     ((λ (f) (‹term› (f f))) (λ (f) (‹term› (f f)))) =                            Substitute (λ (f) (‹term› (f f))) for f.

4     (‹term› ((λ (f) (‹term› (f f))) (λ (f) (‹term› (f f))))) =                Because line 3 = line 2.

5     (‹term› ((λ (m) ((λ (f) (m (f f))) (λ (f) (m (f f))))) ‹term›)) =        Because line 2 = line 1.

6     (‹term› (Y ‹term›))

For this reason Y is called a fixed point combinator. A combinator is a lambda term without free variables. Indeed, Y has no free 
variables. Given a ‹term›0, Y produces a ‹term›1 ≡ (Y ‹term›0) such that (‹term›0 ‹term›1) = ‹term›1. ‹term›1 is called a fixed 
point of ‹term›0. In general: if f(x)=x, then x is called a fixed point of f. Now:

7     (Y (λ (‹var›) ‹body›)) =

8     ((λ (‹var›) ‹body›) (Y (λ (‹var›) ‹body›))) =

9     ‹body› in which (Y (λ (‹var›) ‹body›)) is substituted for ‹var› =

10   ‹body› in which ‹var› is replaced by a term equal to ‹body›: self-reference!

We can use this fact for the construction of lambda terms representing recursive functions:

11   (Y (λ (‹var›0) (λ (‹var›1) ‹body›))) =

12   (λ (‹var›1) ‹body›) in which ‹var›0 is bound to a term equal to (λ (‹var›1) ‹body›): recursion!

Hence in order to prepare a recursive function of the name ‹name›, formal argument ‹formal-argument› and body ‹body›, we write (Y (λ 
(‹name›) (λ (‹formal-argument›) ‹body›))). Y cannot be used in scheme. For example:

(((λ (m) ((λ (f) (m (f f))) (λ (f) (m (f f))))) (λ (!) (λ (n) (if (zero? n) 1 (* n (! (sub1 n))))))) 4)

as an attempt to compute the factorial of 4, does not work. Copy the above expression into DrScheme’s definition window and use 
Debug to see what happens. The reason that the above factorial function does not work is that Scheme evaluates in applicative order. 
Y is not suited for this strategy of reduction. Scheme is caught in an infinite recursion in the underlined subexpression. We must 
postpone the evaluation of (f f) within the underlined subexpression. This can be done as follows:

#lang scheme                                      ; File applicative-order-y-combinator.ss

(((λ (m) ((λ (f) (m (f f))) (λ (f) (m (λ (x) ((f f) x)))))) (λ (!) (λ (n) (if (zero? n) 1 (* n (! (sub1 n))))))) 4)

                                                                            → 24

We can call (λ (m) ((λ (f) (m (f f))) (λ (f) (m (λ (x) ((f f) x)))))) an applicative order Y combinator. Another, more symmetric 
form of this combinator is:

(λ (m)

 ( (λ (f) (m (λ (x) ((f f) x))))

  (λ (f) (m (λ (x) ((f f) x))))))

----- Original Message ----- 
From: "Lightstar" <laalaalovesu at yahoo.com>
To: <plt-scheme at list.cs.brown.edu>
Sent: Saturday, May 23, 2009 8:11 PM
Subject: [plt-scheme] Applicative-order Y Combinator

> How does this function work? (below)
> I think that it is recursion but I have never seen anything use itself as a parameter before... ( (lambda (f) (f f)) ) could you 
> explain this to me please?
> (define Y
>  (lambda (le)
>    ((lambda (f) (f f))
>     (lambda (f)
>       (le (lambda (x) ((f f) x)))))))
> _________________________________________________
>  For list-related administrative tasks:
>  http://list.cs.brown.edu/mailman/listinfo/plt-scheme

Posted on the users mailing list.