#lang racket (define Y-comb (lambda (function-def) ( (lambda (d) (d d)) ; i.e. call yourself (lambda (function-builder) ; delay the evaluation of (function-builder function-builder) until ; it is needed. That is, make it a function, and this is f! (function-def (lambda (y) ((function-builder function-builder) y) ) ) ) ) ) ) ; suppose we want to define mutually recursive functions f and g (define f (lambda (x) (if (< x 0) "f" (g (- x 1)))) ) (define g (lambda (x) (if (< x 0) "g" (f (- x 1)))) ) ; since we have two names, we can't do this directly with the ; Y combinator. But we can collect both functions together under ; one name by having a selector function like this: (define h-select (lambda (s) (if (= 0 s) f g) )) ; (h 0 ) is f, (h 1) is g. So we can expand the definition of f and g ; above, and replace the calls by the (h 0) and (h 1) to get this: (define h (lambda (s) (if (= 0 s) (lambda (x) (if (< x 0) "f" ( (h 1) (- x 1)))) ; i.e. f (lambda (x) (if (< x 0) "g" ( (h 0) (- x 1)))) ; i.e. g )) ) ; this is a simply recursive function with one argument, and so has a ; definition of the form the Y combinator likes. (define h-def (lambda (h) (lambda (s) (if (= 0 s) (lambda (x) (if (< x 0) "f" ( (h 1) (- x 1)))) ; i.e. f (lambda (x) (if (< x 0) "g" ( (h 0) (- x 1)))) ; i.e. g )) ) ) (define h1 (Y-comb h-def))