Lambda Linkedin
Lambda Linkedin
Lambda Linkedin
𝜆as.js
F L O C K of F U N C T I O N S
C O M B I N AT O R S , L A M B D A C A L C U L U S ,
& C H U R C H E N C O D I N G S in J AVA S C R I P T
glebec
Gabriel Lebec glebec
glebec
github.com/glebec/lambda-talk glebec
g_lebec
😭
𝜆a.a
IDENTITY
λ I := 𝜆a.a
JS I = a => a
λ I := 𝜆a.a
JS I = a => a
λ I := 𝜆a.a
JS I = a => a
λ I := 𝜆a.a
JS I = a => a
λ I := 𝜆a.a
JS I = a => a
I := 𝜆a.a
I = a => a
λ Ix=?
JS I(x) === ?
I := 𝜆a.a
I = a => a
λ Ix=x
JS I(x) === x
I := 𝜆a.a
I = a => a
λ II=?
JS I(I) === ?
I := 𝜆a.a
I = a => a
λ II=I
JS I(I) === I
id 5 == 5
𝜆?
FUNCTION
SIGNIFIER 𝜆a.a
PA R A M E T E R VA R I A B L E
FUNCTION
SIGNIFIER 𝜆a.a
PA R A M E T E R VA R I A B L E
FUNCTION
SIGNIFIER 𝜆a.a RETURN
EXPRESSION
PA R A M E T E R VA R I A B L E
FUNCTION
SIGNIFIER 𝜆a.a RETURN
EXPRESSION
LAMBDA ABSTRACTION
𝜆 - C A L C U L U S S Y N TA X
x x
(a) (a)
A P P L I C AT I O N S
fa f(a)
fab f(a)(b)
(f a) b (f(a))(b)
f (a b) f(a(b))
ABSTRACTIONS
𝜆a.b a => b
((𝜆a.a)𝜆b.𝜆c.b)(x)𝜆e.f
β-REDUCTION
((𝜆a.a)𝜆b.𝜆c.b)(x)𝜆e.f
β-REDUCTION
((𝜆a.a)𝜆b.𝜆c.b)(x)𝜆e.f
β-REDUCTION
((𝜆a.a)𝜆b.𝜆c.b)(x)𝜆e.f
= (𝜆b.𝜆c.b) (x)𝜆e.f
β-REDUCTION
((𝜆a.a)𝜆b.𝜆c.b)(x)𝜆e.f
= (𝜆b.𝜆c.b) (x)𝜆e.f
β-REDUCTION
((𝜆a.a)𝜆b.𝜆c.b)(x)𝜆e.f
= (𝜆b.𝜆c.b) (x)𝜆e.f
β-REDUCTION
((𝜆a.a)𝜆b.𝜆c.b)(x)𝜆e.f
= (𝜆b.𝜆c.b) (x)𝜆e.f
= (𝜆c.x) 𝜆e.f
β-REDUCTION
((𝜆a.a)𝜆b.𝜆c.b)(x)𝜆e.f
= (𝜆b.𝜆c.b) (x)𝜆e.f
= (𝜆c.x) 𝜆e.f
β-REDUCTION
((𝜆a.a)𝜆b.𝜆c.b)(x)𝜆e.f
= (𝜆b.𝜆c.b) (x)𝜆e.f
= (𝜆c.x) 𝜆e.f
β-REDUCTION
((𝜆a.a)𝜆b.𝜆c.b)(x)𝜆e.f
= (𝜆b.𝜆c.b) (x)𝜆e.f
= (𝜆c.x) 𝜆e.f
= x
β-REDUCTION*
((𝜆a.a)𝜆b.𝜆c.b)(x)𝜆e.f
= (𝜆b.𝜆c.b) (x)𝜆e.f
= (𝜆c.x) 𝜆e.f
= x
β-NORMAL FORM
*not covered: evaluation order, variable collision avoidance
𝜆f.ff
MOCKINGBIRD
λ M := 𝜆f.ff
JS M = f => f(f)
λ M := 𝜆f.ff
JS M = f => f(f)
λ M := 𝜆f.ff
JS M = f => f(f)
λ M := 𝜆f.ff
JS M = f => f(f)
M := 𝜆f.ff
λ MI=?
JS M(I) === ?
M := 𝜆f.ff
λ MI=II=?
λ MI=II=I
λ MM=?
JS M(M) === ?
M := 𝜆f.ff
λ MM=MM=?
λ MM=MM=MM=Ω
// stack overflow
JS M(M) ===
M(M) ===
M(M) ===
M(M) ===
M(M)
M(M)
===
===
M(M)
M(M)
===
===
M
M
M(M) === M(M) === M(M) === M(M) === M
M(M) === M(M) === M(M) === M(M) === M
M(M) === M(M) === M(M) === M(M) === M
M := 𝜆f.ff
λ ω ω =ω ω =ω ω =Ω
// stack overflow
JS M(M) ===
M(M) ===
M(M) ===
M(M) ===
M(M)
M(M)
===
===
M(M)
M(M)
===
===
M
M
M(M) === M(M) === M(M) === M(M) === M
M(M) === M(M) === M(M) === M(M) === M
M(M) === M(M) === M(M) === M(M) === M
A B S T R A C T I O N S , again
((𝜆a.a)𝜆bc.b)(x)𝜆e.f
β - R E D U C T I O N , again
((𝜆a.a)𝜆bc.b)(x)𝜆e.f
= (𝜆bc.b) (x)𝜆e.f
β - R E D U C T I O N , again
((𝜆a.a)𝜆bc.b)(x)𝜆e.f
= (𝜆bc.b) (x)𝜆e.f
β - R E D U C T I O N , again
((𝜆a.a)𝜆bc.b)(x)𝜆e.f
= (𝜆bc.b) (x)𝜆e.f
= (𝜆c.x) 𝜆e.f
β - R E D U C T I O N , again
((𝜆a.a)𝜆bc.b)(x)𝜆e.f
= (𝜆bc.b) (x)𝜆e.f
= (𝜆c.x) 𝜆e.f
β - R E D U C T I O N , again
((𝜆a.a)𝜆bc.b)(x)𝜆e.f
= (𝜆bc.b) (x)𝜆e.f
= (𝜆c.x) 𝜆e.f
= x
β-NORMAL FORM
𝜆ab.a
KESTREL
λ K := 𝜆ab.a
= 𝜆a.𝜆b.a
JS K = a => b => a
λ K := 𝜆ab.a
= 𝜆a.𝜆b.a
JS K = a => b => a
λ K := 𝜆ab.a
= 𝜆a.𝜆b.a
JS K = a => b => a
λ K := 𝜆ab.a
= 𝜆a.𝜆b.a
JS K = a => b => a
K := 𝜆ab.a
K = a => b => a
λ KMI=?
JS K(M)(I) === ?
K := 𝜆ab.a
K = a => b => a
λ KMI=M
JS K(M)(I) === M
K := 𝜆ab.a
K = a => b => a
λ KMI=M
KIM=?
JS K(M)(I) === M
K(I)(M) === ?
K := 𝜆ab.a
K = a => b => a
λ KMI=M
KIM=I
JS K(M)(I) === M
K(I)(M) === I
const 7 2 == 7
K := 𝜆ab.a
K = a => b => a
λ KIx =I
JS K(I)(x) === I
K := 𝜆ab.a
K = a => b => a
λ KIxy=Iy=?
λ KIxy=Iy=y
λ KIxy=Iy=y
λ KIxy=Iy=y
JS KI = a => b => b
KI = K(I)
KI := 𝜆ab.b
KI = a => b => b
λ KI M K = ?
JS KI(M)(K) === ?
KI := 𝜆ab.b
KI = a => b => b
λ KI M K = K
JS KI(M)(K) === K
KI := 𝜆ab.b
KI = a => b => b
λ KI M K = K
KI K M = ?
JS KI(M)(K) === K
KI(K)(M) === ?
KI := 𝜆ab.b
KI = a => b => b
λ KI M K = K
KI K M = M
JS KI(M)(K) === K
KI(K)(M) === M
?
SCHÖNFINKEL C U R RY S M U L LYA N
M AT H E M AT I C A L L O G I C
F O R M A L N O TAT I O N F O R F U N C T I O N S
1889
PEANO RU S S E L L VO N N E U M A N N GÖDEL KLEENE RO S S E R
PEANO ARITHMETIC
A X I O M AT I C L O G I C · F N N O TAT I O N
PEANO RU S S E L L VO N N E U M A N N GÖDEL KLEENE RO S S E R
F U N C T I O N S A S G R A P H S · C U R RY I N G
P R I N C I P I A M AT H E M AT I C A
1910
PEANO RU S S E L L VO N N E U M A N N GÖDEL KLEENE RO S S E R
R U S S E L L ’ S P A R A D O X · F N N O TAT I O N
C O M B I N AT O RY L O G I C
PEANO RU S S E L L VO N N E U M A N N GÖDEL KLEENE RO S S E R
C O M B I N AT O R S · C U R RY I N G
F U N C T I O N A L S Y S T E M O F S E T T H E O RY
1925
PEANO RU S S E L L VO N N E U M A N N GÖDEL KLEENE RO S S E R
( O V E R L A P P E D W I T H C O M B I N AT O RY L O G I C )
C O M B I N AT O RY L O G I C ( A G A I N )
PEANO RU S S E L L VO N N E U M A N N GÖDEL KLEENE RO S S E R
C O M B I N AT O R S · M A N Y C O N T R I B U T I O N S
DISCOVERS SCHÖNFINKEL
PEANO RU S S E L L VO N N E U M A N N GÖDEL KLEENE RO S S E R
A N E F F E C T I V E M O D E L O F C O M P U TAT I O N
INCONSISTENCY OF SPECIALIZED 𝜆
1931–1936
PEANO RU S S E L L VO N N E U M A N N GÖDEL KLEENE RO S S E R
CONSISTENCY OF PURE 𝜆
S O LV E S T H E D E C I S I O N P R O B L E M
PEANO RU S S E L L VO N N E U M A N N GÖDEL KLEENE RO S S E R
P U B L I S H E S 1 S T F I X E D - P O I N T C O M B I N AT O R
C O M B I N AT O R S
functions with no free variables
𝜆b.b combinator
𝜆b.a not a combinator
𝜆ab.a combinator
𝜆a.ab not a combinator
𝜆abc.c(𝜆e.b) combinator
C O M B I N AT O R S
Sym. Bird 𝜆-Calculus Use Haskell
I Idiot 𝜆a.a identity id
λ CKIM=?
JS C(K)(I)(M) === ?
C := 𝜆fab.fba
C = f => a => b => f(b)(a)
λ CKIM=M
JS C(K)(I)(M) === M
C := 𝜆fab.fba
C = f => a => b => f(b)(a)
λ CKIM=M
JS C(K)(I)(M) === M
C := 𝜆fab.fba
C = f => a => b => f(b)(a)
λ KI I M = M
JS KI(I)(M) === M
C O M B I N AT O R S
Sym. Bird 𝜆-Calculus Use Haskell
I Idiot 𝜆a.a identity id
(𝜆f.ff)𝜆a.a
real computers
machine code
assembly languages
higher-level machine-centric languages
higher-level abstract stateful languages
purely functional programming languages
𝜆 TM
E V E RY T H I N G
CAN BE
FUNCTIONS
…
T R U E FA L S E N O T A N D O R B E Q
λ
JS const result = bool ? exp1 : exp2
λ
JS const result = bool ? exp1 : exp2
// true
λ
JS const result = bool ? exp1 : exp2
// false
λ result := ?
FALSE
KI
λ TRUE := K
FALSE := KI = C K
JS const T = K
const F = KI
λ !p
JS !p
λ NOT p
JS not(p)
F
λ NOT p
T
F
JS not(p)
T
F
λ NOT T
T
F
JS not(T)
T
F
λ NOT F
T
F
JS not(F)
T
λ p F T
JS p (F) (T)
K KI
λ T F T
K KI
JS T (F) (T)
KI K
λ F F T
KI K
JS F (F) (T)
λ NOT := 𝜆p.pFT
JS not(T) === F
not(F) === T
𝜆ab.a 𝜆ba.a
NOT K = KI
λ NOT (KI) = K
𝜆ba.a 𝜆ab.a
JS not(K) === KI
not(KI) === K
C K = KI
λ C (KI) = K
JS const and = ?
λ AND := 𝜆pq.?
F
JS const and = p => q => p(?)(¿)
λ AND := 𝜆pq.p?F
T
JS const and = p => q => p(?)(F)
λ AND := 𝜆pq.pqF
JS const or = ?
λ OR := 𝜆pq.…
T
(q )
F
𝜆pq.p
(q F)
T
q
𝜆pq.p
(q F)
T
q
𝜆pq.p
(NOT q)
𝜆pq.p q (NOT q)
p => q => p(q)(not(q))
CHURCH ENCODINGS: BOOLEANS
Sym. Name 𝜆-Calculus Use
λ N1 NOT T = NOT T = ?
JS n1(not)(T) = not(T) = ?
N1 := 𝜆fa.fa
N1 = f => a => f(a)
λ N1 NOT T = NOT T = F
JS n1(not)(T) = not(T) = F
N2 := 𝜆fa.f(fa)
N2 = f => a => f(f(a))
JS n2(not)(T) = not(not(T)) = ?
N2 := 𝜆fa.f(fa)
N2 = f => a => f(f(a))
JS n2(not)(T) = not(not(T)) = T
N3 := 𝜆fa.f(f(fa))
N3 = f => a => f(f(f(a)))
λ N3NOT T =
NOT (NOT (NOT T))) = F
JS n3(not)(T) = not(not(not(T))) = F
N0 := 𝜆fa.a
N1 :=
λ N2 :=
𝜆fa.fa
𝜆fa.f(fa)
N3 := 𝜆fa.f(f(fa))
JS n0
n1
=
=
f
f
=>
=>
a
a
=>
=>
a
f(a)
n2 = f => a => f(f(a))
n3 = f => a => f(f(f(a)))
N0 := 𝜆fa.a
N3 = f => a => a
λ N0 NOT T = ?
JS n0(not)(T) = ?
N0 := 𝜆fa.a
N3 = f => a => a
λ N0 NOT T = T
JS n0(not)(T) = T
CHURCH ENCODINGS: NUMERALS
Sym. Name 𝜆-Calculus Use
SUCC N1 = N2
SUCC N2 = N3
SUCC (SUCC N1) = N3
λ SUCC := 𝜆n.?
SUCC N1 = N2
JS succ = n => ?
λ SUCC := 𝜆n.?
SUCC 𝜆fa.fa = 𝜆fa.f(fa)
JS succ = n => ?
λ SUCC := 𝜆nfa.f(nfa)
SUCC 𝜆fa.fa = 𝜆fa.f(fa)
λ B NOT NOT T = ?
JS B(not)(not)(T) === ?
B := 𝜆fga.f(ga)
B = f => g => a => f(g(a))
λ B NOT NOT T = T
JS B(not)(not)(T) === T
odd = not . even
C O M B I N AT O R S
Sym. Bird 𝜆-Calculus Use Haskell
I Idiot 𝜆a.a identity id
Mult := 𝜆 n k f . n (k f)
= B = 𝜆 f g a . f (g a)
CHURCH ARITHMETIC
Name 𝜆-Calculus Use
JS is0 = n => ?
λ IS0 := 𝜆n.n func arg
I
N0: N0 (𝜆g.IS0 (g N1) ) (K N0) N0 N0
(B SUCC g)
(K N0)
I
N1: N1 (𝜆g.IS0 (g N1) ) (K N0) N0 N0
(B SUCC g)
I I
N2: N2 (𝜆g.IS0 (g N1) ) (K N0) N0 N1
(B SUCC g)
(SUCC ∘ I)
I
N3: N3 (𝜆g.IS0 (g N1) ) (K N0) N0 N2
(B SUCC g)
…
PA I R F S T S N D P H I
𝜆abf.fab
VIREO
λ V := 𝜆abf.fab
λ VIM
= (𝜆f.f I M)
JS V(I)(M)
// f => f(I)(M)
V := 𝜆abf.fab
V = a => b => f => f(a)(b)
λ VIMK
= (𝜆f.f I M) K = ?
JS V(I)(M)(K)
// (f => f(I)(M))(K) === ?
V := 𝜆abf.fab
V = a => b => f => f(a)(b)
λ VIMK
= (𝜆f.f I M) K = I
JS V(I)(M)(K)
// (f => f(I)(M))(K) === I
V := 𝜆abf.fab
V = a => b => f => f(a)(b)
λ V I M KI
= (𝜆f.f I M) KI = M
JS V(I)(M)(KI)
// (f => f(I)(M))(KI) === M
C O M B I N AT O R S
Sym. Bird 𝜆-Calculus Use Haskell
I Idiot 𝜆a.a identity id
Φ PHI 𝜆p.PAIR (SND p) (SUCC (SND p) copy 2nd to 1st, inc 2nd
Φ PHI 𝜆p.PAIR (SND p) (SUCC (SND p) copy 2nd to 1st, inc 2nd
Φ (M, N7) = ?
Φ := 𝜆p.PAIR (SND p) (SUCC (SND p))
Φ (M, N7) = ( , )
Φ := 𝜆p.PAIR (SND p) (SUCC (SND p))
Φ PHI 𝜆p.PAIR (SND p) (SUCC (SND p) copy 2nd to 1st, inc 2nd
JS eq = B(not)(leq) ???
λ GT := B NOT LEQ
JS eq = B(not)(leq)
λ GT := 𝜆nk.NOT (LEQ n k)
λ GT := B1 NOT LEQ
JS eq = B1(not)(leq)
CHURCH ARITHMETIC: BOOLEAN OPS
Name 𝜆-Calculus Use
KI = KI=CK
B1 = BBB
Th = CI
V= B C Th = B C (C I)
QUESTION
how many combinators
are needed to form a basis?
20? 10? 5?
S TA R L I N G · K E S T R E L
S := 𝜆abc.ac(bc)
K := 𝜆ab.a
THE
SK
C O M B I N AT O R
CALCULUS
I =SKK
I =SKK
V = (S(K((S((S(K((
S(KS))K)))S))(KK))))
((S(K(S((SK)K))))K)
seriously though,
why?
🎮
🤔
🎨
…
ADDENDUM
C O M B I N AT O R S
Sym. Bird 𝜆-Calculus Use Haskell
I Idiot 𝜆a.a identity id
Φ PHI 𝜆p.PAIR (SND p) (SUCC (SND p) copy 2nd to 1st, inc 2nd
CALL BY NAME C A L L B Y VA L U E
(apply to args before reduction) (reduce args before application)
(𝜆ab.b)((𝜆f.ff)𝜆f.ff) x (𝜆ab.b)((𝜆f.ff)𝜆f.ff)x
= (𝜆b.b) x = (𝜆ab.b)((𝜆f.ff)𝜆f.ff)x
= x = (𝜆ab.b)((𝜆f.ff)𝜆f.ff)x
= (𝜆ab.b)((𝜆f.ff)𝜆f.ff)x
= (𝜆ab.b)((𝜆f.ff)𝜆f.ff)x