(define (reduce-once E) (cond ((not (pair? E)) #f) ((lambda-expression? E) #f) ((lambda-expression? (operator E)) (subst (operand E) (argument (operator E)) (body (operator E)))) (else (let ((reduced-operator (reduce-once (operator E)))) (if reduced-operator `(,reduced-operator ,(operand E)) (let ((reduced-operand (reduce-once (operand E)))) (if reduced-operand `(,(operator E) ,reduced-operand) #f))))))) (define (reduce E) (let ((reduced-expression (reduce-once E))) (if reduced-expression (reduce reduced-expression) E))) (define (lambda-expression? E) (and (pair? E) (eq? (type E) 'lambda))) (define (free? x E) (cond ((null? E) #t) ((pair? E) (if (eq? (type E) 'lambda) (if (eq? (argument E) x) #f (free? x (body E))) (or (free? x (operator E)) (free? x (operand E))))) (else (eq? E x)))) (define (subst M x E) (cond ((eq? E x) M) ((not (pair? E)) E) ((lambda-expression? E) (let ((y (argument E)) (E* (body E))) (if (or (eq? x y) (not (free? x E*))) E (if (not (free? y M)) `(lambda (,y) ,(subst M x E*)) (let ((z (gensym))) `(lambda (,z) ,(subst M x (subst z y E*)))))))) (else (list (subst M x (operator E)) (subst M x (operand E)))))) (define operator car) (define operand cadr) (define type car) (define argument caadr) (define body caddr) (define true `(lambda (x) (lambda (y) x))) (define false `(lambda (x) (lambda (y) y))) (define kons `(lambda (x) (lambda (y) (lambda (f) ((f x) y))))) (define kar `(lambda (f) (f ,true))) (define kdr `(lambda (f) (f ,false))) (define nil `(lambda (x) ,true)) (define nil? `(lambda (f) (f (lambda (x) (lambda (y) ,false))))) (define (lambda->sexpr E) (cond ((symbol? E) E) ((zero? (reduce `(((,nil? ,E) 0) 1))) ()) (else (cons (lambda->sexpr (reduce `(,kar ,E))) (lambda->sexpr (reduce `(,kdr ,E))))))) (define succ `(lambda (x) ((,kons x) ,nil))) (define pred kar) (define (number->lambda n) (if (= n 0) nil `(,succ ,(number->lambda (- n 1))))) (define (lambda->number E) (if (zero? (reduce `(((,nil? ,E) 0) 1))) 0 (+ 1 (lambda->number (reduce `(,pred ,E)))))) ;; (u) (define foo `((,kons u) ,nil)) ;; (u v w) (define bar `((,kons u) ((,kons v) ((,kons w) ,nil)))) (define f `(lambda (f) (lambda (x) (((,nil? x) ,nil) ((,kons (,kar x)) (f (,kdr x))))))) ;; An expression which can copy nil... ;; (lambda->sexpr (reduce `((,f ,what!?) ,nil))) => () ;; `((,f ,what!?) ,nil) => ;; `((lambda (x) (((,nil? x) ,nil) ((,kons (,kar x)) (,what!? (,kdr x))))) ,nil) => ;; `(((,nil? ,nil) ,nil) ((,kons (,kar ,nil)) (,what!? (,kdr ,nil)))) => ;; `((,true ,nil) ((,kons (,kar ,nil)) (,what!? (,kdr ,nil)))) => ;; ,nil ;; but fails on lists of length 1 or greater. ;; (lambda->sexpr (reduce `(,(,f ,what!?) ,foo))) => What!? No PeZ! ;; `((,f ,what!?) ,foo) => ;; `((lambda (x) (((,nil? x) ,nil) ((,kons (,kar x)) (,what!? (,kdr x))))) ,foo) => ;; `(((,nil? ,foo) ,nil) ((,kons (,kar ,foo)) (,what!? (,kdr ,foo)))) => ;; `((,false ,nil) ((,kons (,kar ,foo)) (,what!? (,kdr ,foo)))) => ;; `((,kons (,kar ,foo)) (,what!? (,kdr ,foo))) => What!? No PeZ! ;; An expression which can copy lists of length 1... ;; (lambda->sexpr (reduce `(,f (,f ,what!?)) ,foo)) => (u) ;; `((,f (,f ,what!?)) ,foo) => ;; `((lambda (x) (((,nil? x) ,nil) ((,kons (,kar x)) ((,f ,what!?) (,kdr x))))) ,foo) => ;; `(((,nil? ,foo) ,nil) ((,kons (,kar ,foo)) ((,f ,what!?) (,kdr ,foo)))) => ;; `((,false ,nil) ((,kons (,kar ,foo)) ((,f ,what!?) (,kdr ,foo)))) => ;; `((,kons (,kar ,foo)) ((,f ,what!?) (,kdr ,foo))) => ;; `((,kons u) ((,f ,what!?) (,kdr ,foo))) => ;; `((,kons u) ((lambda (x) (((,nil? x) ,nil) ((,kons (,kar x)) (,what!? (,kdr x))))) (,kdr foo)) => ;; `((,kons u) (((,nil? (,kdr foo)) ,nil) ((,kons (,kar (,kdr foo))) (,what!? (,kdr (,kdr foo))))) => ;; `((,kons u) ((,true ,nil) ((,kons (,kar (,kdr foo))) (,what!? (,kdr (,kdr foo))))) => ;; ((,kons u) ,nil) ;; but fails on lists of length 2 or greater. ;; (lambda->sexpr (reduce `(,f (,f ,what!?)) ,bar)) => What!? No PeZ! ;; An expression which can copy lists of length 3 or less. ;; (lambda->sexpr (reduce `(,f (,f (,f (,f what!?)))) ,nil))) => () ;; (lambda->sexpr (reduce `(,f (,f (,f (,f what!?)))) ,foo))) => (u) ;; (lambda->sexpr (reduce `(,f (,f (,f (,f what!?)))) ,bar))) => (u v w) ;; An expression of infinite length which can copy any list. ;; `(,f ...(,f (,f (,f ,what!?)))...) ;; Let there be Y... (define Y '(lambda (f) ((lambda (g) (f (g g))) (lambda (g) (f (g g)))))) ;; Reducing (,Y ,f) once... ;; `(,Y ,f) => `((lambda (g) (,f (g g))) (lambda (g) (,f (g g)))) ;; Let's give this expression a name... (define pez `((lambda (g) (,f (g g))) (lambda (g) (,f (g g))))) ;; Reducing pez yields... ;; pez = ;; `((lambda (g) (,f (g g))) (lambda (g) (,f (g g)))) => ;; `(,f ((lambda (g) (,f (g g))) (lambda (g) (,f (g g))))) = ;; `(,f ,pez) => ;; `(lambda (x) (((,nil? x) ,nil) ((,kons (,kar x)) (,pez (,kdr x))))) ;; Note: Because pez => `(,f ,pez) it is called a "fixed-point" of f. ;; Let's see how (,Y ,f) copies a list of length 1... ;; `((,Y ,f) ,foo) => ;; `(,pez ,foo) => ;; Pez! Give me an f! ;; `((,f ,pez) ,foo) => ;; `((lambda (x) (((,nil? x) ,nil) ((,kons (,kar x)) (,pez (,kdr x))))) ,foo) => ;; `(((,nil? ,foo) ,nil) ((,kons (,kar ,foo)) (,pez (,kdr ,foo)))) => ;; `((,false ,nil) ((,kons (,kar ,foo)) (,pez (,kdr ,foo)))) => ;; `((,kons (,kar ,foo)) (,pez (,kdr ,foo))) => ;; `((,kons u) (,pez (,kdr ,foo))) => ;; Pez! Give me an f! ;; `((,kons u) ((,f ,pez) (,kdr ,foo))) => ;; `((,kons u) ((lambda (x) (((,nil? x) ,nil) ((,kons (,kar x)) (,pez (,kdr x))))) (,kdr ,foo)) => ;; `((,kons u) (((,nil? (,kdr foo)) ,nil) ((,kons (,kar (,kdr ,foo))) (,pez (,kdr (,kdr ,foo)))))) => ;; `((,kons u) ((,true ,nil) ((,kons (,kar (,kdr ,foo))) (,pez (,kdr (,kdr ,foo)))))) => ;; `((,kons u) ,nil) ;; It follows that (,Y ,f) is an expression of finite length which can copy any list!! ;; (lambda->sexpr (reduce `((,Y ,f) ,bar))) => (u v w) (define plus `(lambda (x) (,Y (lambda (f) (lambda (y) (((,nil? y) x) (,succ (f (,pred y))))))))) (define times `(lambda (x) (,Y (lambda (f) (lambda (y) (((,nil? (,pred y)) x) ((,plus x) (f (,pred y)))))))))