other-explanation.scm 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. ;;; Source: https://www.ocf.berkeley.edu/~abhishek/ycode.html
  2. ;;; Let's jump right in. The first form may look a little murky at
  3. ;;; first because of the extra lambda. Try to trace what happens when
  4. ;;; you evaluate ((fact1 fact1) 10); you should get
  5. ;;; (* 10 ((fact1 fact1) 9)) and so on. As you think of this, note
  6. ;;; the crucial (h h) at the end. Why is it necessary?
  7. (define fact1
  8. (lambda (h)
  9. (lambda (n)
  10. (if (= n 1)
  11. 1
  12. (* n ((h h) (- n 1)))))))
  13. ;;; So that works and could certainly serve as the answer to, "How do you do
  14. ;;; recursion with just lambdas?" But what if we really want to take this,
  15. (define F
  16. (lambda (h)
  17. (lambda (n)
  18. (if (= n 1)
  19. 1
  20. (* n (h (- n 1)))))))
  21. ;;; and turn it into a recursive function. Observe that if we already had
  22. ;;; a working factorial function 'fact' then,
  23. ;;; (F fact) ---> fact.
  24. ;;; So F is waiting for the right function to bootstrap itself!
  25. ;;; The Y combinator is the magic that takes us there.
  26. ;;; (Y F) ---> fact
  27. ;;; In other words Y provides a fixed point of F because,
  28. ;;; (F (Y F)) ---> (Y F)
  29. ;;; To frustrate the novice, we should say here, "The rest is just
  30. ;;; currying!" First go back to fact1 again and remove the troublesome
  31. ;;; (h h) by adding another lambda.
  32. (define fact2
  33. (lambda (g)
  34. ((lambda (h)
  35. (lambda (n)
  36. (if (= n 1)
  37. 1
  38. (* n (h (- n 1))))))
  39. (lambda (m) ((g g) m)))))
  40. ;;; This is by no means the only natural way to proceed, but
  41. ;;; unfortunately here all roads don't lead to Rome. Next we look
  42. ;;; for the correct argument to fact2. We want,
  43. ;;; ((fact2 A) 10) = 10!
  44. ;;; or ((fact2 A) 10) ---> (* 10 ((A A) 9))
  45. ;;; So the right A is... fact2! Indeed ((fact2 fact2) n) works.
  46. ;;; Cleaning up a little,
  47. (define fact3
  48. (lambda (g)
  49. (F (lambda (m) ((g g) m)))))
  50. ;;; and finally,
  51. (define fact
  52. ((lambda (g)
  53. (F (lambda (m) ((g g) m))))
  54. (lambda (g)
  55. (F (lambda (m) ((g g) m))))))
  56. ;;; is the factorial function. Now it is clear that the Y combinator should be,
  57. (define Y
  58. (lambda (f)
  59. ((lambda (u)
  60. (f (lambda (x) ((u u) x))))
  61. (lambda (v)
  62. (f (lambda (x) ((v v) x)))))))
  63. ;;; This is also called the Turing fixed point combinator. How
  64. ;;; pleasing and symmetric it looks! For greater obscurity, we could
  65. ;;; also compress it as,
  66. (define Yobs
  67. (lambda (f)
  68. ((lambda (f)
  69. (f f))
  70. (lambda (u)
  71. (f (lambda (x) ((u u) x)))))))
  72. ;;; which has the effect of inducing a powerful headache.