- Invented by Alonzo Church (1920s)
- Equally expressive to the Turing Machine(s)
- Formal Language
- Computational Model
- Lisp (1950s)
- ML
- Haskell
- “Lambda Expressions” in almost every modern programming language
- Simple Computational Model
- to describe structure and behaviour (E.g. Operational Semantics, Type Systems)
- to reason and prove
- Explains why things in FP are like they are
- Pure Functions
- Higher-Order Functions
- Currying
- Lazy Evaluation
- Understand FP Compilers
- Introduce FP stuff into other languages
- Write your own compiler
- GHC uses an enriched Lambda Calculus internally
\begin{align*}
t ::= & & \text{Terms:}
& \ x & \text{Variable} \
& \ λ x.t & \text{Abstraction} \
& \ t \ t & \text{Application}
\end{align*}
Think: Function Definitions
Think: Parameters
Think: Function Calls
\begin{align*}
\onslide<1->{ & ( λ \color<3->{orange}{x} . & λ y . & \color<3->{orange}{x} & y & ) & \color<3->{orange}{a} & & b & & \onslide<2->{ \text{Substitute
\onslide<4->{→ & & ( λ \color<6->{cyan}{y} . & \color{orange}{a} & \color<6->{cyan}{y} & ) & & & \color<6->{cyan}{b} & & \onslide<5->{\text{Substitute
- We use parentheses to clearify what’s meant
- Applications associate to the left
\begin{equation*} s \ t \ u ≡ (s \ t) \ u \end{equation*}
- Abstractions expand as much to the right as possible
\begin{equation*} λ x . λ y . x \ y \ x ≡ λ x . ( λ y . (x \ y \ x ) ) \end{equation*}
\begin{equation*} λ x . λ y . x \ y \ z \end{equation*}
- $λ y$
- $y$ is bound, $x$ and $z$ are free
- $λ x$
- $x$ and $y$ are bound, $z$ is free
- $λ x$, $λ y$
- binders
- A combinator
$id ≡ λ x . x$ - Y, S, K, I …
- Functions that take or return functions
- Are there “by definition”
\begin{equation*} \underbrace{ \underbrace{λ x.x}Abstraction \quad \underbrace{λ y.y}Abstraction }Application → \underbrace{λ y.y}Abstraction \end{equation*}
- Take a function with
$n$ arguments - Create a function that takes one argument and returns a function with
$n-1$ arguments
-
(+1)
Section in Haskell $(λ x . λ y . + x \ y) \ 1 → λ y . + \ 1 \ y$
- Partial Function Application is there “by definition”
- You can use this stunt to “curry” in every language that supports “Lambda Expressions”
- Moses Schönfinkel
- If you want to sound smart: Schönfinkeling
Iff (if and only if)
(λ x . \underbrace{(λ y . y)}f \ x) \ a →_η \underbrace{(λ y . y)}f \ a
\end{gather*}
If
- Everything (Term) is an Expression
- No statements
- No “destructive” Assignments
- The reason why FP Languages promote pure functions
- But you could invent a built-in function to manipulate “state”…
- We learned how to write down and talk about Lambda Calculus Terms
- How to evaluate them?
- Different Strategies
- Interesting outcomes
- RedEx
- \textbf{Red}ucible \textbf{Ex}pression
- Always an Application
\begin{equation*} \underbrace{ (λ x.x) \ (\underbrace{(λ y.y) \ (λ z.\underbrace{(λ a.a) \ z}RedEx)}RedEx) }RedEx \end{equation*}
- Any RedEx, Any Time
- Like in Arithmetics
- Too vague for programming…
\begin{align*} \onslide<1->{ & \alert<2->{ (λ x.x) \ ((λ y.y) \ (λ z.(λ a.a) \ z)) } \ } \onslide<3->{→ & \alert<4->{(λ y.y) \ (λ z.(λ a.a) \ z) } \ } \onslide<5->{→ & λ z.\alert<6->{(λ a.a) \ z } \ } \onslide<7->{→ & λ z.z } \end{align*}
- Left-most, Outer-most RedEx
\begin{align*} \onslide<1->{ & \alert<2->{ (λ x.x) \ ((λ y.y) \ (λ z.(λ a.a) \ z)) } \ } \onslide<3->{→ & \alert<4->{(λ y.y) \ (λ z.(λ a.a) \ z) } \ } \onslide<5->{→ & λ z.(λ a.a) \ z \ } \onslide<6->{¬\to} \end{align*}
- like Normal Order Reduction, but no reductions inside Abstractions
- Abstractions are values
- lazy, non-strict
- Parameters are not evaluated before they are used
- Optimization: Save results → Call-by-Need
\begin{align*} \onslide<1->{ & (λ x.x) \ \alert<2->{((λ y.y) \ (λ z.(λ a.a) \ z)) } \ } \onslide<3->{ → & \alert<4->{(λ x.x) \ (λ z.(λ a.a) \ z)} \ } \onslide<5->{ → & λ z.(λ a.a) \ z \ } \onslide<6->{¬ →} \end{align*}
- Outer-most, only if right-hand side was reduced to a value
- No reductions inside Abstractions
- Abstractions are values
- eager, strict
- Parameters are evaluated before they are used
- Encode Data into the Lambda Calculus
- To simplify our formulas, let’s say that we have declarations
\begin{gather*}
id ≡ λ x.x
id \ y → y
\end{gather*}
false & ≡ & λ t. λ f.f \ \ \onslide<2->{ test & ≡ & λ c . λ t . λ f . c \ t \ f } \end{align*} \begin{align*} \onslide<3->{& \alert<4->{test} \ true \ a \ b }
\onslide<5->{≡ & \ \alert<6->{(λ c . λ t . λ f . c \ t \ f) \ true } \ a \ b } \ \onslide<7->{→ & \ \alert<8->{(λ t . λ f . true \ t \ f) \ a} \ b } \ \onslide<9->{→ & \ \alert<10->{(λ f . true \ a \ f) \ b }} \ \onslide<11->{→ & \alert<12->{true} \ a \ b } \ \onslide<13->{≡ & \alert<14->{(λ t. λ f.t) \ a} \ b } \ \onslide<15->{→ & \alert<16->{(λ f.a) \ b } } \ \onslide<17->{→ & a } \end{align*} \begin{align*} true & ≡ & λ t. λ f.t
false & ≡ & λ t. λ f.f \ \ \onslide<2->{ and & ≡ & λ p . λ q . p \ q \ p } \end{align*} \begin{align*} \onslide<3->{& \alert<4->{and} \ true \ false }
\onslide<5->{≡ & \alert<6->{(λ p . λ q . p \ q \ p) \ true } \ false } \ \onslide<7->{→ & \alert<8->{(λ q . true \ q \ true) \ false } } \ \onslide<9->{→ & \alert<10->{true} \ false \ true } \ \onslide<11->{≡ & \alert<12->{(λ t. λ f.t) \ false} \ true } \ \onslide<13->{→ & \alert<14->{(λ f .false) \ true } } \ \onslide<15->{→ & false } \end{align*}
\begin{equation*} λ p . λ q . p \ p \ q \end{equation*}
\begin{align*} \onslide<1->{pair & ≡ & λ x. λ y . λ z . z \ x \ y }\onslide<2->{ first & ≡ & (λ p. p) \ λ x . λ y . x \ second & ≡ & (λ p. p) \ λ x . λ y . y } \end{align*} \begin{align*} \onslide<3->{pairAB & ≡ & \alert<4->{pair} \ a \ b }
\onslide<5->{& ≡ & \alert<6->{(λ x. λ y . λ z . z\ x\ y) \ a } \ b } \ \onslide<7->{& → & \alert<8->{(λ y . λ z . z\ a\ y) \ b } } \ \onslide<9->{& → & λ z . z\ a \ b } \ \onslide<10->{& ≡ & pair’ab } \ \end{align*} \begin{align*} \onslide<1->{pair & ≡ & λ x. λ y . λ z . z \ x \ y
first & ≡ & (λ p. p) \ λ x . λ y . x \ pair’ab & ≡ & λ z . z\ a \ b \ } \end{align*} \begin{align*} \onslide<2->{& & \alert<3->{first} \ pair’ab }
\onslide<4->{& ≡ & \alert<5->{(λ p. p) \ (λ x . λ y . x) \ pair’ab} } \ \onslide<6->{& → & \alert<7->{pair’ab} \ (λ x . λ y . x) } \ \onslide<8->{& ≡ & \alert<9->{(λ z . z\ a \ b) \ (λ x . λ y . x) }} \ \onslide<10->{& → & \alert<11->{(λ x . λ y . x) \ a} \ b } \ \onslide<12->{& → & \alert<13->{(λ y . a) \ b } } \ \onslide<14->{& → & a} \end{align*} Every natural number can be defined with $0$ and a successor function \begin{align*} 0 & ≡ & λ f. λ x. x
1 & ≡ & λ f. λ x. f \ x \ 2 & ≡ & λ f. λ x. f \ (f \ x) \ 3 & ≡ & λ f. λ x. f \ (f \ (f \ x)) \ \end{align*}
- $0$
- $f$ is evaluated $0$ times
- $1$
- $f$ is evaluated once
- $x$
- can be every lambda term
1 & ≡ & λ f. λ x. f \ x \ } \ \onslide<2->{ successor & ≡ & λ n. λ f. λ x. f \ (n \ f \ x) } \end{align*} \begin{align*} \onslide<+(2)->{& & \alert<+(2)->{successor} \ 1 }
\onslide<+(2)->{& ≡ & \alert<+(2)->{(λ n. λ f. λ x. f \ (n \ f \ x)) \ 1 } } \ \onslide<+(2)->{& → & λ f. λ x. f \ (\alert<+(2)->{1} \ f \ x) } \ \onslide<+(2)->{& ≡ & λ f. λ x. f \ (\alert<+(2)->{(λ f. λ x. f \ x) \ f } \ x) } \ \onslide<+(2)->{& → & λ f. λ x. f \ (\alert<+(2)->{(λ x. f \ x) \ x}) } \ \onslide<+(2)->{& → & λ f. λ x. f \ (f \ x) } \ \onslide<+(2)->{& ≡ & 2} \end{align*} We use Normal Order Reduction to reduce inside abstractions! \begin{align*} \onslide<+->{0 & ≡ & λ f. λ x. x }
\ \onslide<+->{plus & ≡ & λ m. λ n. λ f. λ x. m \ f \ (n \ f \ x) } \end{align*} \begin{align*} \onslide<+->{& & \alert<+->{plus} \ 0 \ 0}
\onslide<+->{& ≡ & \alert<+->{(λ m. λ n. λ f. λ x. m \ f \ (n \ f \ x)) \ 0 } \ 0 } \ \onslide<+->{& → & \alert<+->{(λ n. λ f. λ x. 0 \ f \ (n \ f \ x)) \ 0 }} \ \onslide<+->{& → & λ f. λ x. \alert<+->{0} \ f \ (0 \ f \ x) } \ \onslide<+->{& ≡ & λ f. λ x. \alert<+->{(λ f. λ x. x) \ f} \ (0 \ f \ x) } \ \onslide<+->{& → & λ f. λ x. \alert<+->{(λ x. x) \ (0 \ f \ x) }} \ \onslide<+->{& → & λ f. λ x. \alert<+->{0} \ f \ x } \ \onslide<+->{& ≡ & λ f. λ x. \alert<+->{(λ f. λ x. x) \ f } \ x } \ \onslide<+->{& → & λ f. λ x. \alert<+->{(λ x. x) \ x }} \ \onslide<+->{& → & λ f. λ x. x } \ \onslide<+->{& ≡ & 0 } \end{align*}
- Hope you enjoyed this talk and learned something new.
- Hope it wasn’t too much math and dusty formulas … :)
- Easy to understand
- How to compile to the Lambda Calculus?
- Out-of-print, but freely available
- Types systems explained by building interpreters and proving properties
- Very “mathematical”, but very complete and self-contained