### SlideShare for iOS

by Linkedin Corporation

FREE - On the App Store

A brief intro to the Y Combinator, using Clojure.

A brief intro to the Y Combinator, using Clojure.

- Total Views
- 512
- Views on SlideShare
- 511
- Embed Views

- Likes
- 0
- Downloads
- 1
- Comments
- 0

https://www.linkedin.com | 1 |

- 1. We are OUDL. Organization for the Understanding of Dynamic Languages http://meetup.com/dynamic/Wednesday, August 22, 12We are programming language enthusiastsCheck us out on Meetup.comAll events have been by members, for membersEach event has a theme, a selected pastry or baked good, and a horrible logo
- 2. What makes Objective C dynamic?Wednesday, August 22, 12
- 3. What makes Objective C dynamic? Kamehameha Bakery donuts Otto Cake cheesecake Cake Couture cupcakes Fendu Bakery croissants & cookies Saint Germain Bakery palmiersWednesday, August 22, 12
- 4. Mahalo.Wednesday, August 22, 12
- 5. Y combinator Examples in Clojure. Also includes: blenders and kittens. Caveat emptor: I make no effort to teach you Clojure. Kyle Oba @mudphone Pas de ChocolatWednesday, August 22, 12
- 6. Not this one.Wednesday, August 22, 12Paul Graham did name his company after the *REAL* Y combinator.But, why?
- 7. This one. (defn Y [g] ((fn [x] (x x)) (fn [x] (g (fn [y] ((x x) y))))))Wednesday, August 22, 12Which is this thing, in Clojure.
- 8. Let’s get started. Here’s a non-recursive deﬁnition of factorial, using the Y combinator.Wednesday, August 22, 12Here it is. Thank you, good night and good luck.
- 9. (defn Y [g] ((fn [x] (x x)) (fn [x] (g (fn [y] ((x x) y)))))) (defn almost-factorial [f] (fn [n] (if (= n 0) 1 (* n (f (dec n)))))) (defn factorial [n] ((Y almost-factorial) n))Wednesday, August 22, 12Here it is. Thank you, good night and good luck.
- 10. Questions?Wednesday, August 22, 12
- 11. An example: 5! (factorial 5) = 5 * 4 * 3 * 2 * 1 = 120 (defn factorial [n] (if (= n 0) 1 (* n (factorial (dec n)))))Wednesday, August 22, 12Let’s back up. This is how a sane person would deﬁne factorial... recursively.
- 12. here to here? (defn factorial (defn almost-factorial [n] [f] (if (= n 0) (fn [n] 1 (if (= n 0) (* n (factorial (dec n))))) 1 (* n (f (dec n)))))) (defn Y [g] ((fn [x] (x x)) (fn [x] (g (fn [y] ((x x) y)))))) (defn factorial [n] ((Y almost-factorial) n))Wednesday, August 22, 12Recursive deﬁnition to non-recursive
- 13. 2 Things 1) recursion 2) functionsWednesday, August 22, 12
- 14. 2 Things 1) recursion 2) functionsWednesday, August 22, 12
- 15. “The Y combinator allows recursion recursion... as a set of rewrite rules, without requiring native recursion support in the language.” -- Someone on WikipediaWednesday, August 22, 12
- 16. replace “native recursion” with manual recursionWednesday, August 22, 12
- 17. (defn factorial [n] (defn fact (if (= n 0) [n] 1 (if (= n 0) (* n (factorial (dec n))))) 1 (* n (ERROR (dec n)))))Wednesday, August 22, 12
- 18. (defn factorial [n] (defn fact (if (= n 0) [n] 1 (if (= n 0) (* n (factorial (dec n))))) 1 (* n (ERROR (dec n))))) n = 0 OK n = 1 BOOM!Wednesday, August 22, 12
- 19. (defn factorial [n] (defn fact (defn fact (if (= n 0) [n] [n] 1 (if (= n 0) (if (= n 0) (* n (factorial (dec n))))) 1 1 (* n (ERROR (dec n))))) (* n (ERROR (dec n) (defn fact (defn fact [n] [n] (if (= n 0) (if (= n 0) 1 1 n = 0 OK (* n (ERROR (dec n))))) (* n (ERROR (dec n)) (defn fact (defn fact [n] [n] n = 1 BOOM! (if (= n 0) (if (= n 0) 1 1 (* n (ERROR (dec n))))) (* n (ERROR (dec n) (defn fact (defn fact [n] [n] (if (= n 0) (if (= n 0) 1 1 (* n (ERROR (dec n))))) (* n (ERROR (dec n)Wednesday, August 22, 12
- 20. (defn fact (fn [n] (fn [n] [n] (if (= n 0) (if (= n (if (= n 0) 1 1 1 (* n (ERROR (dec n))))) (* n ( (* n (ERROR (dec n))))) (fn [n] (fn [n] (if (= n 0) (if (= n 0) 1 1 (* n (ERROR (dec n))))) (* n (ERROR (dec n)))))Wednesday, August 22, 12
- 21. (defn fact (fn [n] (fn [n] [n] (if (= n 0) (if (= n (if (= n 0) 1 1 1 (* n (ERROR (dec n))))) (* n ( (* n (ERROR (dec n))))) (fn [n] (fn [n] (if (= n 0) (if (= n 0) 1 1 (* n (ERROR (dec n))))) (* n (ERROR (dec n))))) n=0 n=1 n=2 n=3 n=4Wednesday, August 22, 12
- 22. replace “native recursion” with manual recursion “rewrite rules”Wednesday, August 22, 12
- 23. 2 Things 1) recursion 2) functionsWednesday, August 22, 12
- 24. 2 Things 1) recursion 2) functionsWednesday, August 22, 12
- 25. Functions are machines. Functions are relationships, between inputs and outputs.Wednesday, August 22, 12
- 26. A function is a blender.Wednesday, August 22, 12
- 27. FIRST ORDER BLENDER A normal blender that consumes single input and creates output.Wednesday, August 22, 12
- 28. FIRST ORDER BLENDER A normal blender that consumes single input and creates output. HIGHER ORDER BLENDER A special blender that consumes a blender and outputs another blender.Wednesday, August 22, 12
- 29. FIRST ORDER BLENDER A normal blender that consumes single input and creates output. HIGHER ORDER BLENDER A special blender that consumes a blender and outputs another blender. FIXPOINT (BLENDER) COMBINATOR Y Consumes a blender and produces a new blender that can consume any number of inputs.Wednesday, August 22, 12
- 30. ONEWednesday, August 22, 12
- 31. ONE (defn almost-factorial [f] (fn [n] (if (= n 0) 1 (* n (f (dec n))))))Wednesday, August 22, 12
- 32. ONE ANY (defn almost-factorial [f] (fn [n] (if (= n 0) 1 (* n (f (dec n))))))Wednesday, August 22, 12
- 33. ONE ANY Y (defn almost-factorial [f] factorial (fn [n] (if (= n 0) 1 (* n (f (dec n))))))Wednesday, August 22, 12
- 34. if you squint (defn factorial (defn almost-factorial [n] [f] (if (= n 0) (fn [n] 1 (if (= n 0) (* n (factorial (dec n))))) 1 (* n (f (dec n)))))) (defn Y [g] ((fn [x] (x x)) (fn [x] (g (fn [y] ((x x) y)))))) (defn factorial [n] ((Y almost-factorial) n))Wednesday, August 22, 12Derivation not possible in 3 minutes.
- 35. I’m so sorry. No kittens were blended during the creation of this presentation.Wednesday, August 22, 12
- 36. No really, done now. No kittens were blended during the creation of this presentation.Wednesday, August 22, 12
- 37. A Clojure Primer PARENTHESIS (+ 1 2 3) ;; => 6 PREFIX NOTATION (operator arg1 arg2 arg3) FUNCTIONS (defn multby2 (fn [n] (* n 2)) [n] (* n 2)) ;; (multby2 4) => 8Wednesday, August 22, 121) First, a primer on LISP & Clojure- parens for function call- preﬁx notation, followed by arguments2) And, function deﬁnition and anonymous functions
- 38. (defn simple-factorial [n] (if (= n 0) 1 (* n (simple-factorial (dec n)))))Wednesday, August 22, 12Here, we remove the recursive deﬁnition. Kind of delaying it, for now.
- 39. (defn simple-factorial [n] (if (= n 0) 1 (* n (simple-factorial (dec n))))) (defn part [self n] (if (= n 0) 1 (* n (self self (dec n))))) ;; (part part 5) => 120Wednesday, August 22, 12Here, we remove the recursive deﬁnition. Kind of delaying it, for now.
- 40. (defn simple-factorial [n] (if (= n 0) 1 (* n (simple-factorial (dec n))))) (defn part [self n] (if (= n 0) 1 (* n (self self (dec n))))) ;; (part part 5) => 120Wednesday, August 22, 12Change part to take a single arg, returning a function that takes n.
- 41. (defn part [self n] (if (= n 0) 1 (* n (self self (dec n))))) ;; (part part 5) => 120 (defn part2 [self] (fn [n] (if (= n 0) 1 (* n ((self self) (dec n)))))) ;; ((part2 part2) 5) => 120Wednesday, August 22, 12Change part to take a single arg, returning a function that takes n.
- 42. (defn part [self n] (if (= n 0) 1 (* n (self self (dec n))))) ;; (part part 5) => 120 (defn part2 [self] (fn [n] (if (= n 0) 1 (* n ((self self) (dec n)))))) ;; ((part2 part2) 5) => 120Wednesday, August 22, 12Replace (self self) with f, which blows up in a Stack Overﬂow... but, we press on.
- 43. (defn part2 [self] (fn [n] (if (= n 0) 1 (* n ((self self) (dec n)))))) ;; ((part2 part2) 5) => 120 (defn part3 [self] (let [f (self self)] (fn [n] (if (= n 0) 1 (* n (f (dec n)))))))Wednesday, August 22, 12Replace (self self) with f, which blows up in a Stack Overﬂow... but, we press on.
- 44. (defn part2 [self] (fn [n] (if (= n 0) 1 (* n ((self self) (dec n)))))) ;; ((part2 part2) 5) => 120 (defn part3 [self] (let [f (self self)] (fn [n] (if (= n 0) 1 (* n (f (dec n)))))))Wednesday, August 22, 12Bury, the (self self) call in a lambda.
- 45. (defn part3 [self] (let [f (self self)] (fn [n] (if (= n 0) 1 (* n (f (dec n))))))) (defn part4 [self] (let [f (fn [y] ((self self) y))] (fn [n] (if (= n 0) 1 (* n (f (dec n)))))))Wednesday, August 22, 12Bury, the (self self) call in a lambda.
- 46. (defn part3 [self] (let [f (self self)] (fn [n] (if (= n 0) 1 (* n (f (dec n))))))) (defn part4 [self] (let [f (fn [y] ((self self) y))] (fn [n] (if (= n 0) 1 (* n (f (dec n)))))))Wednesday, August 22, 12Rip out the function that looks almost like the factorial function. This is what we’regeneralizing. The Y combinator computes the ﬁxpoint of this function.
- 47. (defn part4 [self] (let [f (fn [y] ((self self) y))] (fn [n] (if (= n 0) 1 (* n (f (dec n))))))) (defn almost-factorial [f] (fn [n] (if (= n 0) 1 (* n (f (dec n))))))Wednesday, August 22, 12Rip out the function that looks almost like the factorial function. This is what we’regeneralizing. The Y combinator computes the ﬁxpoint of this function.
- 48. (defn part4 [self] (let [f (fn [y] ((self self) y))] (fn [n] (if (= n 0) 1 (* n (f (dec n))))))) (defn almost-factorial [f] (fn [n] (if (= n 0) 1 (* n (f (dec n))))))Wednesday, August 22, 12Insert almost-factorial into the part function.
- 49. (defn almost-factorial [f] (fn [n] (if (= n 0) 1 (* n (f (dec n)))))) (defn part5 [self] (let [f (fn [y] ((self self) y))] (almost-factorial f)))Wednesday, August 22, 12Insert almost-factorial into the part function.
- 50. (defn almost-factorial [f] (fn [n] (if (= n 0) 1 (* n (f (dec n)))))) (defn part5 [self] (let [f (fn [y] ((self self) y))] (almost-factorial f)))Wednesday, August 22, 12fact5 is a working factorial function, but we can generalize it
- 51. (defn part5 [self] (let [f (fn [y] ((self self) y))] (almost-factorial f))) (defn fact5 [n] ((part5 part5) n))Wednesday, August 22, 12fact5 is a working factorial function, but we can generalize it
- 52. (defn part5 [self] (let [f (fn [y] ((self self) y))] (almost-factorial f))) (defn fact5 [n] ((part5 part5) n))Wednesday, August 22, 12here we embed the deﬁnition the “part” function
- 53. (defn fact5 [n] ((part5 part5) n)) (def fact6 (let [part (fn [self] (let [f (fn [y] ((self self) y))] (almost-factorial f)))] (part part)))Wednesday, August 22, 12here we embed the deﬁnition the “part” function
- 54. (defn fact5 [n] ((part5 part5) n)) (def fact6 (let [part (fn [self] (let [f (fn [y] ((self self) y))] (almost-factorial f)))] (part part)))Wednesday, August 22, 12rename part => xand self => xfor kicks really
- 55. (def fact6 (let [part (fn [self] (let [f (fn [y] ((self self) y))] (almost-factorial f)))] (part part))) (def fact7 (let [x (fn [x] (let [f (fn [y] ((x x) y))] (almost-factorial f)))] (x x)))Wednesday, August 22, 12rename part => xand self => xfor kicks really
- 56. (def fact6 (let [part (fn [self] (let [f (fn [y] ((self self) y))] (almost-factorial f)))] (part part))) (def fact7 (let [x (fn [x] (let [f (fn [y] ((x x) y))] (almost-factorial f)))] (x x)))Wednesday, August 22, 12replace the (x x) invocation with a lambda of the same
- 57. (def fact7 (let [x (fn [x] (let [f (fn [y] ((x x) y))] (almost-factorial f)))] (x x))) (def fact8 ((fn [x] (x x)) (fn [x] (let [f (fn [y] ((x x) y))] (almost-factorial f)))))Wednesday, August 22, 12replace the (x x) invocation with a lambda of the same
- 58. (def fact7 (let [x (fn [x] (let [f (fn [y] ((x x) y))] (almost-factorial f)))] (x x))) (def fact8 ((fn [x] (x x)) (fn [x] (let [f (fn [y] ((x x) y))] (almost-factorial f)))))Wednesday, August 22, 12Rename to Yand generalize, by accepting a function g and using this to replace almost-factorial
- 59. (def fact8 ((fn [x] (x x)) (fn [x] (let [f (fn [y] ((x x) y))] (almost-factorial f))))) (defn nearly-Y [g] ((fn [x] (x x)) (fn [x] (let [f (fn [y] ((x x) y))] (g f)))))Wednesday, August 22, 12Rename to Yand generalize, by accepting a function g and using this to replace almost-factorial
- 60. (def fact8 ((fn [x] (x x)) (fn [x] (let [f (fn [y] ((x x) y))] (almost-factorial f))))) (defn nearly-Y [g] ((fn [x] (x x)) (fn [x] (let [f (fn [y] ((x x) y))] (g f)))))Wednesday, August 22, 12Replace f with the anonymous function bound to it
- 61. (defn nearly-Y [g] ((fn [x] (x x)) (fn [x] (let [f (fn [y] ((x x) y))] (g f))))) (defn Y [g] ((fn [x] (x x)) (fn [x] (g (fn [y] ((x x) y))))))Wednesday, August 22, 12Replace f with the anonymous function bound to it
- 62. (defn nearly-Y [g] ((fn [x] (x x)) (fn [x] (let [f (fn [y] ((x x) y))] (g f))))) (defn Y [g] ((fn [x] (x x)) (fn [x] (g (fn [y] ((x x) y))))))Wednesday, August 22, 12
- 63. (defn Y [g] ((fn [x] (x x)) (fn [x] (g (fn [y] ((x x) y)))))) (defn factorial [n] ((Y almost-factorial) n))Wednesday, August 22, 12
- 64. (defn Y [g] ((fn [x] (x x)) (fn [x] (g (fn [y] ((x x) y)))))) I’m so sorry. (defn factorial [n] ((Y almost-factorial) n))Wednesday, August 22, 12
- 65. I’m so sorry. No kittens were blended during the creation of this presentation.Wednesday, August 22, 12
- 66. (defn almost-factorial (Y almost-factorial) [f] (fn [n] ;; ((Y almost-factorial) 5) => 120 (if (= n 0) 1 (* n (f (dec n))))))Wednesday, August 22, 12
- 67. (defn almost-factorial (Y almost-factorial) [f] (fn [n] ;; ((Y almost-factorial) 5) => 120 (if (= n 0) 1 (* n (f (dec n)))))) YWednesday, August 22, 12
- 68. (defn almost-factorial (Y almost-factorial) [f] (fn [n] ;; ((Y almost-factorial) 5) => 120 (if (= n 0) 1 (* n (f (dec n)))))) Y FACTORIALWednesday, August 22, 12
- 69. (defn almost-factorial (Y almost-factorial) [f] (fn [n] ;; ((Y almost-factorial) 5) => 120 (if (= n 0) 1 (* n (f (dec n)))))) (defn fact (defn fact [n] [n] (if (= n 0) (if (= n 0) Y 1 1 (* n (ERROR (dec n))))) (* n (ERROR (dec n))))) (defn fact (defn fact [n] [n] (if (= n 0) (if (= n 0) 1 1 (* n (ERROR (dec n))))) (* n (ERROR (d FACTORIALWednesday, August 22, 12
- 70. (defn almost-factorial [f] (fn [n] (if (= n 0) 1 (* n (f (dec n)))))) Y factorialWednesday, August 22, 12
- 71. (defn almost-factorial [f] (fn [n] (if (= n 0) 1 (* n (f (dec n)))))) Y factorialWednesday, August 22, 12
- 72. (defn almost-factorial [f] (fn [n] (if (= n 0) 1 ONE (* n (f (dec n)))))) Y factorialWednesday, August 22, 12
- 73. (defn almost-factorial [f] (fn [n] (if (= n 0) ANY 1 ONE (* n (f (dec n)))))) Y factorialWednesday, August 22, 12

Full NameComment goes here.