Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
SlideShare a Scribd company logo
λ calculus
λf· (λx· f (x x)) (λx· f (x x))
Attila Magyar
Microsec Ltd.
2016
 1930s
 Turing complete universal model of computation
 Treats functions "anonymously"
 Typed or untyped
 Examples:
 λx· x
 (λx· x)y = y
Syntax
// Java
(x, y) -> { return x + y; }
// Groovy
{ x, y -> x + y }
Single input, single output
function add(x, y) {
return x + y;
}
add(1, 2);
function add(x) {
return function(y) {
return x + y;
}
}
add(1)(2)
FizzBuzz
 1, 2, Fizz, 4, Buzz, Fizz, 7, 8, Fizz, Buzz, 11, Fizz, 13, 14, FizzBuzz, 16, 17,
Fizz, 19, Buzz, Fizz, 22, 23, Fizz, Buzz, 26, Fizz, 28, 29, FizzBuzz, 31, 32,
Fizz, 34, Buzz, Fizz, ...
Fizz - if divisible by 3
Buzz - if divisible by 5
FizzBuzz - if divisible by 3 and 5
Number - otherwise
FizzBuzz Java
for (int i = 1; i <= 100; i++) {
if (i % 15 == 0) {
System.out.println("FizzBuzz")
} else if (i % 3 == 0) {
System.out.println("Fizz");
} else if (i % 5 == 0) {
System.out.println("Buzz");
} else {
System.out.println(String.valueOf(i));
}
}
Booleans
TRUE = { a -> { b -> a } }
FALSE = { a -> { b -> b } }
E.g.: TRUE(x)(y) == x
Numbers
ZERO = { f -> { x -> x } }
ONE = { f -> { x -> f(x) } }
TWO = { f -> { x -> f(f(x)) } }
THREE = { f -> { x -> f(f(f(x))) } }
Numbers
SUCCESSOR = { n ->
{ f -> { x ->
f(n(f)(x))
} }
}
Predecessor
PAIR = { x -> { y ->
{ f -> f(x)(y) }
} }
FIRST = { p ->
p( { x -> { y -> x } } )
}
SECOND = { p ->
p( { x -> { y -> y } } )
}
Predecessor
PREDECESSOR = { n ->
FIRST(
n
({ p -> p({ first -> { second ->
PAIR(second)(SUCCESSOR(second)) } })
})
(PAIR(ZERO)(ZERO))
)
}
Subtract
SUB = { n -> { m ->
m(PREDECESSOR)(n)
} }
IS_ZERO = { n ->
n( { ignore -> FALSE } )(TRUE)
}
LTE = { n -> { m ->
IS_ZERO(SUB(n)(m))
} }
Div/Mod
def div(n, d) {
d > n ? 0 : 1 + div(n - d, d)
}
def mod(n, m) {
m > n ? n : mod(n - m, m)
}
Div/Mod - Y Combinator
YC = {
le -> ({ f -> f(f) })({ f -> le { x -> f(f)(x) } })
}
λf. (λx. f (x x))(λx. f (x x))
Div/Mod - Y Combinator
DIV = YC { recur -> { n -> { d ->
LTE(d)(n)({ w -> SUCCESSOR(recur(SUB(n)(d)) (d) ) (w) })(ZERO)
} } }
MOD = YC { recur -> { n -> { m ->
LTE(m)(n)({ w -> recur(SUB(n)(m))(m) (w) })(n)
} } }
DEMO 1
Lists
[False|*] -> [y|*] -> [False|*] -> [x|*] -> [True|True]
CAR = { xs -> FIRST(SECOND(xs)) }
CDR = { xs -> SECOND(SECOND(xs)) }
EMPTY = PAIR(TRUE)(TRUE)
IS_EMPTY = FIRST
Lists
CONS = { xs -> { x ->
PAIR(FALSE)(PAIR(x)(xs))
} }
RANGE = { upto ->
upto({ a -> CONS(a)(PREDECESSOR(CAR(a))) })(CONS(EMPTY)(upto))
}
Lists
B = TEN
F = ELEVEN
I = TWELVE
U = THIRTEEN
Z = FOURTEEN
FIZZ = CONS(CONS(CONS(CONS(EMPTY)(Z))(Z))(I))(F)
BUZZ = CONS(CONS(CONS(CONS(EMPTY)(Z))(Z))(U))(B)
FIZZBUZZ = CONS(CONS(CONS(CONS(BUZZ)(Z))(Z))(I))(F)
DEMO 2
Lists: Fold Left / Fold Right
fold( { each, resul_so_far -> each+ resul_so_far }, [1,2,3,4,5] );
[1,2,3,4,5] -> 1 + 2 + 3 + 4 + 5
Lists: Fold Left / Fold Right
FOLDL = YC { recur -> { xs -> { f -> { a ->
IS_EMPTY(xs)(a)({ w ->recur(CDR(xs))(f)(f(a)(CAR(xs)))(w) })
} } } }
FOLDR = YC { recur -> { xs -> { f -> { a ->
IS_EMPTY(xs)(a)({ w-> f(recur(CDR(xs))(f)(a))(CAR(xs))(w) })
} } } }
Map
Lists: Map, Reverse
MAP = { xs -> { f ->
FOLDR(xs)( { lst -> { each -> CONS(lst)( f(each) ) } } )(EMPTY)
} }
REVERSE = { xs ->
FOLDL(xs)( { lst -> { each -> CONS(lst)(each) } } )(EMPTY)
}
DEMO 3
Num2str
NUM2STR = { num ->
IS_ZERO(num)
({w -> CONS(EMPTY)(ZERO)(w)})({w2 -> REVERSE(YC {
recur -> { n -> IS_ZERO(n)(EMPTY)( {w ->
CONS(recur(DIV(n)(TEN)))(MOD(n)(TEN))(w)
})}}(num))(w2) })
}
FizzBuzz
GENERATE_FIZZBUZZ = { n ->
MAP(RANGE(n))({ each ->
IS_ZERO(MOD(each)(FIFTEEN))(FIZZBUZZ)({ w ->
IS_ZERO(MOD(each)(FIVE))(BUZZ)({ w2 ->
IS_ZERO(MOD(each)(THREE))(FIZZ)(NUM2STR(each))(w2) })(w) })
})
}
DEMO 4 DEMO 5
References
 Church encoding
 https://en.wikipedia.org/wiki/Church_encoding
 Programming with nothing by Tom Stuart
 https://codon.com/programming-with-nothing
 On Understanding Data Abstraction, Revisited by William R. CooK
 http://www.cs.utexas.edu/~wcook/Drafts/2009/essay.pdf
 Ruby Conf 12 - Y Not- Adventures in Functional Programming by Jim Weirich
 https://www.youtube.com/watch?v=FITJMJjASUs

More Related Content

Lambda calculus

  • 1. λ calculus λf· (λx· f (x x)) (λx· f (x x)) Attila Magyar Microsec Ltd. 2016
  • 2.  1930s  Turing complete universal model of computation  Treats functions "anonymously"  Typed or untyped  Examples:  λx· x  (λx· x)y = y
  • 3. Syntax // Java (x, y) -> { return x + y; } // Groovy { x, y -> x + y }
  • 4. Single input, single output function add(x, y) { return x + y; } add(1, 2); function add(x) { return function(y) { return x + y; } } add(1)(2)
  • 5. FizzBuzz  1, 2, Fizz, 4, Buzz, Fizz, 7, 8, Fizz, Buzz, 11, Fizz, 13, 14, FizzBuzz, 16, 17, Fizz, 19, Buzz, Fizz, 22, 23, Fizz, Buzz, 26, Fizz, 28, 29, FizzBuzz, 31, 32, Fizz, 34, Buzz, Fizz, ... Fizz - if divisible by 3 Buzz - if divisible by 5 FizzBuzz - if divisible by 3 and 5 Number - otherwise
  • 6. FizzBuzz Java for (int i = 1; i <= 100; i++) { if (i % 15 == 0) { System.out.println("FizzBuzz") } else if (i % 3 == 0) { System.out.println("Fizz"); } else if (i % 5 == 0) { System.out.println("Buzz"); } else { System.out.println(String.valueOf(i)); } }
  • 7. Booleans TRUE = { a -> { b -> a } } FALSE = { a -> { b -> b } } E.g.: TRUE(x)(y) == x
  • 8. Numbers ZERO = { f -> { x -> x } } ONE = { f -> { x -> f(x) } } TWO = { f -> { x -> f(f(x)) } } THREE = { f -> { x -> f(f(f(x))) } }
  • 9. Numbers SUCCESSOR = { n -> { f -> { x -> f(n(f)(x)) } } }
  • 10. Predecessor PAIR = { x -> { y -> { f -> f(x)(y) } } } FIRST = { p -> p( { x -> { y -> x } } ) } SECOND = { p -> p( { x -> { y -> y } } ) }
  • 11. Predecessor PREDECESSOR = { n -> FIRST( n ({ p -> p({ first -> { second -> PAIR(second)(SUCCESSOR(second)) } }) }) (PAIR(ZERO)(ZERO)) ) }
  • 12. Subtract SUB = { n -> { m -> m(PREDECESSOR)(n) } } IS_ZERO = { n -> n( { ignore -> FALSE } )(TRUE) } LTE = { n -> { m -> IS_ZERO(SUB(n)(m)) } }
  • 13. Div/Mod def div(n, d) { d > n ? 0 : 1 + div(n - d, d) } def mod(n, m) { m > n ? n : mod(n - m, m) }
  • 14. Div/Mod - Y Combinator YC = { le -> ({ f -> f(f) })({ f -> le { x -> f(f)(x) } }) } λf. (λx. f (x x))(λx. f (x x))
  • 15. Div/Mod - Y Combinator DIV = YC { recur -> { n -> { d -> LTE(d)(n)({ w -> SUCCESSOR(recur(SUB(n)(d)) (d) ) (w) })(ZERO) } } } MOD = YC { recur -> { n -> { m -> LTE(m)(n)({ w -> recur(SUB(n)(m))(m) (w) })(n) } } }
  • 17. Lists [False|*] -> [y|*] -> [False|*] -> [x|*] -> [True|True] CAR = { xs -> FIRST(SECOND(xs)) } CDR = { xs -> SECOND(SECOND(xs)) } EMPTY = PAIR(TRUE)(TRUE) IS_EMPTY = FIRST
  • 18. Lists CONS = { xs -> { x -> PAIR(FALSE)(PAIR(x)(xs)) } } RANGE = { upto -> upto({ a -> CONS(a)(PREDECESSOR(CAR(a))) })(CONS(EMPTY)(upto)) }
  • 19. Lists B = TEN F = ELEVEN I = TWELVE U = THIRTEEN Z = FOURTEEN FIZZ = CONS(CONS(CONS(CONS(EMPTY)(Z))(Z))(I))(F) BUZZ = CONS(CONS(CONS(CONS(EMPTY)(Z))(Z))(U))(B) FIZZBUZZ = CONS(CONS(CONS(CONS(BUZZ)(Z))(Z))(I))(F)
  • 21. Lists: Fold Left / Fold Right fold( { each, resul_so_far -> each+ resul_so_far }, [1,2,3,4,5] ); [1,2,3,4,5] -> 1 + 2 + 3 + 4 + 5
  • 22. Lists: Fold Left / Fold Right FOLDL = YC { recur -> { xs -> { f -> { a -> IS_EMPTY(xs)(a)({ w ->recur(CDR(xs))(f)(f(a)(CAR(xs)))(w) }) } } } } FOLDR = YC { recur -> { xs -> { f -> { a -> IS_EMPTY(xs)(a)({ w-> f(recur(CDR(xs))(f)(a))(CAR(xs))(w) }) } } } }
  • 23. Map
  • 24. Lists: Map, Reverse MAP = { xs -> { f -> FOLDR(xs)( { lst -> { each -> CONS(lst)( f(each) ) } } )(EMPTY) } } REVERSE = { xs -> FOLDL(xs)( { lst -> { each -> CONS(lst)(each) } } )(EMPTY) }
  • 26. Num2str NUM2STR = { num -> IS_ZERO(num) ({w -> CONS(EMPTY)(ZERO)(w)})({w2 -> REVERSE(YC { recur -> { n -> IS_ZERO(n)(EMPTY)( {w -> CONS(recur(DIV(n)(TEN)))(MOD(n)(TEN))(w) })}}(num))(w2) }) }
  • 27. FizzBuzz GENERATE_FIZZBUZZ = { n -> MAP(RANGE(n))({ each -> IS_ZERO(MOD(each)(FIFTEEN))(FIZZBUZZ)({ w -> IS_ZERO(MOD(each)(FIVE))(BUZZ)({ w2 -> IS_ZERO(MOD(each)(THREE))(FIZZ)(NUM2STR(each))(w2) })(w) }) }) }
  • 29. References  Church encoding  https://en.wikipedia.org/wiki/Church_encoding  Programming with nothing by Tom Stuart  https://codon.com/programming-with-nothing  On Understanding Data Abstraction, Revisited by William R. CooK  http://www.cs.utexas.edu/~wcook/Drafts/2009/essay.pdf  Ruby Conf 12 - Y Not- Adventures in Functional Programming by Jim Weirich  https://www.youtube.com/watch?v=FITJMJjASUs