oudl y combinator

73
We are OUDL. Organization for the Understanding of Dynamic Languages http://meetup.com/dynamic/ Wednesday, August 22, 12 We are programming language enthusiasts Check us out on Meetup.com All events have been by members, for members Each event has a theme, a selected pastry or baked good, and a horrible logo

Upload: kyle-oba

Post on 20-Jan-2015

297 views

Category:

Technology


6 download

DESCRIPTION

A brief intro to the Y Combinator, using Clojure.

TRANSCRIPT

Page 1: OUDL Y Combinator

We are OUDL.Organization for the Understanding of Dynamic Languages

http://meetup.com/dynamic/

Wednesday, August 22, 12

We 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

Page 2: OUDL Y Combinator

What makes Objective C dynamic?

Wednesday, August 22, 12

Page 3: OUDL Y Combinator

What makes Objective C dynamic?

Cake Couture cupcakes

Otto Cake cheesecake

Fendu Bakery croissants & cookies

Kamehameha Bakery donuts

Saint Germain Bakery palmiers

Wednesday, August 22, 12

Page 4: OUDL Y Combinator

Mahalo.

Wednesday, August 22, 12

Page 5: OUDL Y Combinator

Y combinatorExamples in Clojure.

Also includes: blenders and kittens.

Kyle Oba @mudphone

Pas de Chocolat

Caveat emptor: I make no effort to teach you Clojure.

Wednesday, August 22, 12

Page 6: OUDL Y Combinator

Not this one.

Wednesday, August 22, 12

Paul Graham did name his company after the *REAL* Y combinator.But, why?

Page 7: OUDL Y Combinator

(defn Y [g] ((fn [x] (x x)) (fn [x] (g (fn [y] ((x x) y))))))

This one.

Wednesday, August 22, 12

Which is this thing, in Clojure.

Page 8: OUDL Y Combinator

Let’s get started.

Here’s a non-recursive definition of factorial,

using the Y combinator.

Wednesday, August 22, 12

Here it is. Thank you, good night and good luck.

Page 9: OUDL Y Combinator

(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, 12

Here it is. Thank you, good night and good luck.

Page 10: OUDL Y Combinator

Questions?

Wednesday, August 22, 12

Page 11: OUDL Y Combinator

(factorial 5) = 5 * 4 * 3 * 2 * 1 = 120

(defn factorial [n] (if (= n 0) 1 (* n (factorial (dec n)))))

An example: 5!

Wednesday, August 22, 12

Let’s back up. This is how a sane person would define factorial... recursively.

Page 12: OUDL Y Combinator

(defn factorial [n] (if (= n 0) 1 (* n (factorial (dec n)))))

(defn factorial [n] ((Y almost-factorial) n))

here to here?

(defn almost-factorial [f] (fn [n] (if (= n 0) 1 (* n (f (dec n))))))

(defn Y [g] ((fn [x] (x x)) (fn [x] (g (fn [y] ((x x) y))))))

Wednesday, August 22, 12

Recursive definition to non-recursive

Page 13: OUDL Y Combinator

2 Things

1) recursion

2) functions

Wednesday, August 22, 12

Page 14: OUDL Y Combinator

2 Things

1) recursion2) functions

Wednesday, August 22, 12

Page 15: OUDL Y Combinator

“The Y combinator allows recursion...as a set of rewrite rules,

without requiring native recursion support in the language.”

-- Someone on Wikipedia

allows recursion

without requiring native recursion

Wednesday, August 22, 12

Page 16: OUDL Y Combinator

replace“native recursion”

withmanual recursion

Wednesday, August 22, 12

Page 17: OUDL Y Combinator

(defn factorial [n] (if (= n 0) 1 (* n (factorial (dec n)))))

(defn fact [n] (if (= n 0) 1 (* n (ERROR (dec n)))))

Wednesday, August 22, 12

Page 18: OUDL Y Combinator

(defn factorial [n] (if (= n 0) 1 (* n (factorial (dec n)))))

(defn fact [n] (if (= n 0) 1 (* n (ERROR (dec n)))))

n = 0 OK

n = 1 BOOM!

Wednesday, August 22, 12

Page 19: OUDL Y Combinator

(defn factorial [n] (if (= n 0) 1 (* n (factorial (dec n)))))

(defn fact [n] (if (= n 0) 1 (* n (ERROR (dec n)))))

(defn fact [n] (if (= n 0) 1 (* n (ERROR (dec n)))))

(defn fact [n] (if (= n 0) 1 (* n (ERROR (dec n)))))

(defn fact [n] (if (= n 0) 1 (* n (ERROR (dec n)))))

(defn fact [n] (if (= n 0) 1 (* n (ERROR (dec n)))))

(defn fact [n] (if (= n 0) 1 (* n (ERROR (dec n)))))

(defn fact [n] (if (= n 0) 1 (* n (ERROR (dec n)))))

(defn fact [n] (if (= n 0) 1 (* n (ERROR (dec n)))))

n = 0 OK

n = 1 BOOM!

Wednesday, August 22, 12

Page 20: OUDL Y Combinator

(defn fact [n] (if (= n 0) 1 (* n (ERROR (dec n)))))

(fn [n] (if (= n 0) 1 (* n (ERROR (dec n)))))

(fn [n] (if (= n 0) 1 (* n (ERROR (dec n)))))

(fn [n] (if (= n 0) 1 (* n (ERROR (dec n)))))

(fn [n] (if (= n 0) 1 (* n (ERROR (dec n)))))

Wednesday, August 22, 12

Page 21: OUDL Y Combinator

(defn fact [n] (if (= n 0) 1 (* n (ERROR (dec n)))))

(fn [n] (if (= n 0) 1 (* n (ERROR (dec n)))))

(fn [n] (if (= n 0) 1 (* n (ERROR (dec n)))))

(fn [n] (if (= n 0) 1 (* n (ERROR (dec n)))))

(fn [n] (if (= n 0) 1 (* n (ERROR (dec n)))))

n = 0 n = 1 n = 2 n = 3 n = 4

Wednesday, August 22, 12

Page 22: OUDL Y Combinator

replace“native recursion”

withmanual recursion“rewrite rules”

Wednesday, August 22, 12

Page 23: OUDL Y Combinator

2 Things

1) recursion

2) functions

Wednesday, August 22, 12

Page 24: OUDL Y Combinator

2 Things

1) recursion

2) functions

Wednesday, August 22, 12

Page 25: OUDL Y Combinator

Functions are machines.

Functions are relationships,between inputs and outputs.

Wednesday, August 22, 12

Page 26: OUDL Y Combinator

A function is a blender.

Wednesday, August 22, 12

Page 27: OUDL Y Combinator

FIRST ORDER BLENDERA normal blender that consumes single input

and creates output.

Wednesday, August 22, 12

Page 28: OUDL Y Combinator

A special blender that consumes a blender and outputs another blender.

HIGHER ORDER BLENDER

FIRST ORDER BLENDERA normal blender that consumes single input

and creates output.

Wednesday, August 22, 12

Page 29: OUDL Y Combinator

A special blender that consumes a blender and outputs another blender.

HIGHER ORDER BLENDER

FIRST ORDER BLENDERA normal blender that consumes single input

and creates output.

YConsumes a blender and produces a new blender that

can consume any number of inputs.

FIXPOINT (BLENDER) COMBINATOR

Wednesday, August 22, 12

Page 30: OUDL Y Combinator

ONE

Wednesday, August 22, 12

Page 31: OUDL Y Combinator

ONE

(defn almost-factorial [f] (fn [n] (if (= n 0) 1 (* n (f (dec n))))))

Wednesday, August 22, 12

Page 32: OUDL Y Combinator

ONE

(defn almost-factorial [f] (fn [n] (if (= n 0) 1 (* n (f (dec n))))))

ANY

Wednesday, August 22, 12

Page 33: OUDL Y Combinator

ONE

(defn almost-factorial [f] (fn [n] (if (= n 0) 1 (* n (f (dec n))))))

ANY

Y

factorial

Wednesday, August 22, 12

Page 34: OUDL Y Combinator

(defn factorial [n] (if (= n 0) 1 (* n (factorial (dec n)))))

(defn factorial [n] ((Y almost-factorial) n))

if you squint

(defn almost-factorial [f] (fn [n] (if (= n 0) 1 (* n (f (dec n))))))

(defn Y [g] ((fn [x] (x x)) (fn [x] (g (fn [y] ((x x) y))))))

Wednesday, August 22, 12

Derivation not possible in 3 minutes.

Page 35: OUDL Y Combinator

I’m so sorry.

No kittens were blended during the creation of this presentation.Wednesday, August 22, 12

Page 36: OUDL Y Combinator

No really, done now.

No kittens were blended during the creation of this presentation.Wednesday, August 22, 12

Page 37: OUDL Y Combinator

(operator arg1 arg2 arg3)

(defn multby2 [n] (* n 2));; (multby2 4) => 8

(fn [n] (* n 2))

A Clojure Primer

PREFIX NOTATION

(+ 1 2 3);; => 6

PARENTHESIS

FUNCTIONS

Wednesday, August 22, 12

1) First, a primer on LISP & Clojure- parens for function call- prefix notation, followed by arguments2) And, function definition and anonymous functions

Page 38: OUDL Y Combinator

(defn simple-factorial [n] (if (= n 0) 1 (* n (simple-factorial (dec n)))))

Wednesday, August 22, 12

Here, we remove the recursive definition. Kind of delaying it, for now.

Page 39: OUDL Y Combinator

(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) => 120

Wednesday, August 22, 12

Here, we remove the recursive definition. Kind of delaying it, for now.

Page 40: OUDL Y Combinator

(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) => 120

Wednesday, August 22, 12

Change part to take a single arg, returning a function that takes n.

Page 41: OUDL Y Combinator

(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) => 120

Wednesday, August 22, 12

Change part to take a single arg, returning a function that takes n.

Page 42: OUDL Y Combinator

(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) => 120

Wednesday, August 22, 12

Replace (self self) with f, which blows up in a Stack Overflow... but, we press on.

Page 43: OUDL Y Combinator

(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, 12

Replace (self self) with f, which blows up in a Stack Overflow... but, we press on.

Page 44: OUDL Y Combinator

(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, 12

Bury, the (self self) call in a lambda.

Page 45: OUDL Y Combinator

(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, 12

Bury, the (self self) call in a lambda.

Page 46: OUDL Y Combinator

(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, 12

Rip out the function that looks almost like the factorial function. This is what we’re generalizing. The Y combinator computes the fixpoint of this function.

Page 47: OUDL Y Combinator

(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, 12

Rip out the function that looks almost like the factorial function. This is what we’re generalizing. The Y combinator computes the fixpoint of this function.

Page 48: OUDL Y Combinator

(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, 12

Insert almost-factorial into the part function.

Page 49: OUDL Y Combinator

(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, 12

Insert almost-factorial into the part function.

Page 50: OUDL Y Combinator

(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, 12

fact5 is a working factorial function, but we can generalize it

Page 51: OUDL Y Combinator

(defn part5 [self] (let [f (fn [y] ((self self) y))] (almost-factorial f)))

(defn fact5 [n] ((part5 part5) n))

Wednesday, August 22, 12

fact5 is a working factorial function, but we can generalize it

Page 52: OUDL Y Combinator

(defn fact5 [n] ((part5 part5) n))

(defn part5 [self] (let [f (fn [y] ((self self) y))] (almost-factorial f)))

Wednesday, August 22, 12

here we embed the definition the “part” function

Page 53: OUDL Y Combinator

(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, 12

here we embed the definition the “part” function

Page 54: OUDL Y Combinator

(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, 12

rename part => xand self => xfor kicks really

Page 55: OUDL Y Combinator

(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, 12

rename part => xand self => xfor kicks really

Page 56: OUDL Y Combinator

(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, 12

replace the (x x) invocation with a lambda of the same

Page 57: OUDL Y Combinator

(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, 12

replace the (x x) invocation with a lambda of the same

Page 58: OUDL Y Combinator

(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, 12

Rename to Yand generalize, by accepting a function g and using this to replace almost-factorial

Page 59: OUDL Y Combinator

(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, 12

Rename to Yand generalize, by accepting a function g and using this to replace almost-factorial

Page 60: OUDL Y Combinator

(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, 12

Replace f with the anonymous function bound to it

Page 61: OUDL Y Combinator

(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

Replace f with the anonymous function bound to it

Page 62: OUDL Y Combinator

(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

Page 63: OUDL Y Combinator

(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

Page 64: OUDL Y Combinator

(defn Y [g] ((fn [x] (x x)) (fn [x] (g (fn [y] ((x x) y))))))

(defn factorial [n] ((Y almost-factorial) n))

I’m so sorry.

Wednesday, August 22, 12

Page 65: OUDL Y Combinator

I’m so sorry.

No kittens were blended during the creation of this presentation.Wednesday, August 22, 12

Page 66: OUDL Y Combinator

(defn almost-factorial [f] (fn [n] (if (= n 0) 1 (* n (f (dec n))))))

(Y almost-factorial);; ((Y almost-factorial) 5) => 120

Wednesday, August 22, 12

Page 67: OUDL Y Combinator

(defn almost-factorial [f] (fn [n] (if (= n 0) 1 (* n (f (dec n))))))

(Y almost-factorial);; ((Y almost-factorial) 5) => 120

Y

Wednesday, August 22, 12

Page 68: OUDL Y Combinator

(defn almost-factorial [f] (fn [n] (if (= n 0) 1 (* n (f (dec n))))))

(Y almost-factorial);; ((Y almost-factorial) 5) => 120

Y

FACTORIALWednesday, August 22, 12

Page 69: OUDL Y Combinator

(defn almost-factorial [f] (fn [n] (if (= n 0) 1 (* n (f (dec n))))))

(Y almost-factorial);; ((Y almost-factorial) 5) => 120

Y

FACTORIAL

(defn fact [n] (if (= n 0) 1 (* n (ERROR (dec n)))))

(defn fact [n] (if (= n 0) 1 (* n (ERROR (dec n)))))

(defn fact [n] (if (= n 0) 1 (* n (ERROR (dec n)))))

(defn fact [n] (if (= n 0) 1 (* n (ERROR (dec n)))))

Wednesday, August 22, 12

Page 70: OUDL Y Combinator

(defn almost-factorial [f] (fn [n] (if (= n 0) 1 (* n (f (dec n))))))

Y

factorial

Wednesday, August 22, 12

Page 71: OUDL Y Combinator

(defn almost-factorial [f] (fn [n] (if (= n 0) 1 (* n (f (dec n))))))

Y

factorial

Wednesday, August 22, 12

Page 72: OUDL Y Combinator

(defn almost-factorial [f] (fn [n] (if (= n 0) 1 (* n (f (dec n))))))

Y

factorial

ONE

Wednesday, August 22, 12

Page 73: OUDL Y Combinator

(defn almost-factorial [f] (fn [n] (if (= n 0) 1 (* n (f (dec n))))))

Y

factorial

ONE ANY

Wednesday, August 22, 12