Top Banner
Deriving the Y Combinator Yuta Okazaki Recurse Center Spring 2 2015
25
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: Deriving the Y Combinator

Deriving the Y Combinator

Yuta Okazaki!Recurse Center Spring 2 2015

Page 2: Deriving the Y Combinator

Recursive Function

factorial = function(n){ if(n == 0){ return 1 } else{ n * factorial(n - 1) } }

Pseudo Code

Page 3: Deriving the Y Combinator

Recursive Functionlet’s simplify this to an ‘infinite’ function.

fact-forever = function(n){ n * fact-forever(n - 1) }

Page 4: Deriving the Y Combinator

Recursive FunctionWhat if we can’t use a variable?

fact-forever = function(n){ n * fact-forever(n - 1) }

Page 5: Deriving the Y Combinator

Recursive Function

What is this inside ‘fact-forever’ gonna be?

fact-forever = function(n){ n * fact-forever(n - 1) }

Page 6: Deriving the Y Combinator

function(n){!

n * (n - 1)!

}

Recursive FunctionI’m imagining if we have a ‘magical function’, that prepares itself again when we need it…

Page 7: Deriving the Y Combinator

Thought Experimentwith Scheme(Lisp)

Page 8: Deriving the Y Combinator

Thought Experiment #1Is it possible to think of a lambda, which

returns a lambda, that takes ‘itself’ as an argument?

((lambda(me)(me me)) (lambda(x)(quote hi)))

Page 9: Deriving the Y Combinator

Thought Experiment #1Is it possible to think of a lambda, which

returns a lambda, that takes ‘itself’ as an argument?

((lambda(me)(me me)) (lambda(x)(quote hi)))

=> ‘hi

Page 10: Deriving the Y Combinator

((lambda(me)(me me)) (lambda(x)( )))

Thought Experiment #2Since ‘me’ function takes ‘me’ as an argument, isn’t it fun if we can somehow use it inside it?

quote hi

Page 11: Deriving the Y Combinator

((lambda(me)(me me)) (lambda(x)( )))

Thought Experiment #2Since ‘me’ function takes ‘me’ as an argument, isn’t it fun if we can somehow use it inside it?

x

Page 12: Deriving the Y Combinator

((lambda(me)(me me)) (lambda(x)( )))

Thought Experiment #2Since ‘me’ function takes ‘me’ as an argument, isn’t it fun if we can somehow use it inside it?

=> expects 1 argument, but found none.

x

Page 13: Deriving the Y Combinator

((lambda(me)(me me)) (lambda(x)( )))

Thought Experiment #3Yeah my bad, x is a lambda expecting

one argument. so… pass in x itself maybe?

x

Page 14: Deriving the Y Combinator

((lambda(me)(me me)) (lambda(x)( )))

Thought Experiment #3Yeah my bad, x is a lambda expecting

one argument. so… pass in x itself maybe?

xx

=>

Page 15: Deriving the Y Combinator

((lambda(me)(me me)) (lambda(x)( )))

Thought Experiment #3Yeah my bad, x is a lambda expecting

one argument. so… pass in x itself maybe?

xx

((lambda(x)(x x)) (lambda(x)(x x)))=>

Page 16: Deriving the Y Combinator

((lambda(me)(me me)) (lambda(x)( )))

Thought Experiment #3Yeah my bad, x is a lambda expecting

one argument. so… pass in x itself maybe?

=> infinite loop!

xx

((lambda(x)(x x)) (lambda(x)(x x)))=>

Page 17: Deriving the Y Combinator

Thought Experiment #3

This is the Javascript version of same thing.

function(x){ return x(x)}(function(x){return x(x)})

Page 18: Deriving the Y Combinator

((lambda(me)(me me)) (lambda(x)( )))

Resume the ProblemSo, how can we use this piece

with the original problem?

xx

function(n) n * (n - 1)

Page 19: Deriving the Y Combinator

((lambda(x) x )(quote hi))

Functional RefactoringWrap Function

((lambda(y)((lambda(x)x)y))(quote hi))

if you have a lambda that takes one argument, you can wrap it with another lambda which also takes one argument, and call it with that argument, you still get the same result.

Page 20: Deriving the Y Combinator

((lambda(me)( me me )) (lambda(x)

Combine themSo, here I use a twisted version of Wrap Function,

in order to accumulate the calculation.

(lambda(number)(number * (

( x x )))

(number - 1))))

Page 21: Deriving the Y Combinator

((lambda(me)( me me )) (lambda(x)

Combine themSo, here I use a twisted version of Wrap Function,

in order to accumulate the calculation.

(lambda(number)(number * (

( x x )

)) (number - 1))))

Page 22: Deriving the Y Combinator

((lambda(me)( me me )) (lambda(x)

Combine themSo, here I use a twisted version of Wrap Function,

in order to accumulate the calculation.

(lambda(number)(number * (( x x )

)) (number - 1))))

Page 23: Deriving the Y Combinator

((lambda(me)( me me )) (lambda(x)

Combine themSo, here I use a twisted version of Wrap Function,

in order to accumulate the calculation.

(lambda(number)(number * (( x x )

)) (number - 1))))

Page 24: Deriving the Y Combinator

Ω Combinator

((lambda(me)( me me )) (lambda(x)

The code below is an application of Ω Combinator.

(lambda(number)(number * (( x x )

)) (number - 1))))

Demo Available

Page 25: Deriving the Y Combinator

Where’s Y Combinator?

Y Combinator is a nicer form of Omega Combinator. If you want to derive one, please talk to me!

(lambda(le) ((lambda(f)(f f)) (lambda(f) (le (lambda(x) ((f f) x))))))

Twitter @kenzan100