lambda demystified: into the heart of functional...
TRANSCRIPT
Lambda Demystified: Into the Heart of FunctionalProgramming
Jim Burton & Aidan Delaney
1 / 45
What is the �-Calculus?
The �-calculus (�C) is a simple, elegant abstract model offunctions and their application.
It’s important because it provides the inspiration and theoreticalfoundation for functional programming, and the entire model ofcomputation that focuses on what to compute, rather than how.
2 / 45
A lightning tour of the �-Calculus
�C is also important because we can use this simple model ofcomputation to work out what happens when our programs run,and to reason about the complexity of algorithms we have yet toimplement.
There is a long history of using �C to define the semantics ofprogramming languages. We’ll define a very simple language basedon �C today.
Reading papers about extensions to programming languages andtheir type systems, snippets of �C will crop up all over the place.
3 / 45
The Church of Church
Alonzo Church came up with �C in 1936. He used it to investigateproblems in computability, the same problems Turing was workingon at the time. Church gave an answer to the Halting Problemindependently of Turing.
4 / 45
Origin of the functional paradigm
The comparison with Turing’s model of computation (which camelater) is interesting. Even if Turing’s model is hypothetical, athought experiment, it is concrete, compared to Church’s abstractmathematical model.
�C is like software in which we don’t care about the underlyingimplementation whereas the Turing machine specifies how themachine will work.
5 / 45
What is the �-Calculus?
So, in this model for functional application,
Everything is an anonymous (higher-order, first class)function,
We can create new functions, and supply arguments tofunctions to “evaluate” them, and
that’s it.
Each function takes a single argument.
6 / 45
What is the �-Calculus?
We are talking about the untyped �-calculus, its simplest form.
�C + types + equality forms the basis of functional programminglanguages, Haskell, ML etc.
Note that there is no equality in the untyped �C. We can’t say ingeneral whether two lambda-terms are the same.
7 / 45
The untyped �-CalculusNotation
Grammar for � terms, e.
1 e := x #variables
2 | � x . e #abstractions
3 | e e #application
8 / 45
Scope
Abstractions contain variables which are free or bound. x is boundin M i↵ it is in the scope of �x in M. Otherwise, it is free in M.
x is bound: (�x .(�y .M x))
x is free: (�y .M x)
9 / 45
Application
Application reduces or simplifies an expression and is carried out bysubstitution.
Applying (�x .M)N means replacing x with N in M (and strippingo↵ the binding).
We write this M[N/x ]. Doing so might mean making changes tobound variables by renaming them.
10 / 45
↵-conversion
In (�x .(�y .M x))y we need to rename the inner y duringapplication to something “fresh”.
Otherwise we would end up with (�y .M y), which isn’t what wewanted.
Renaming variables is called ↵-conversion.
11 / 45
Notation
We can get rid of some �s and parentheses by writing
(�x .(�y .(�z .M)))
as
�xyz .M
.But don’t forget this is not a single function taking threearguments, functions only ever take one.
12 / 45
� and ⌘ reduction, normal forms
There are two ways to evaluate or reduce � terms:
1 function application, called �-reduction, and
2 throwing away redundant terms, called ⌘-reduction. I.e. in theterm (�x .M x), if x is not in the free variables of M, then wecan reduce the term to M.
13 / 45
�⌘-normal form (�⌘NF)
If P = (�x .M)N and Q = M[N/x ] we write P !� Q.
Similarly, if x is not in the free variables of M we write(�x .M x) !⌘ M.
A �⌘-reduction is a finite or infinite sequence of � and⌘-contractions, within which ↵-conversion is allowed.
A term is in �⌘-normal form i↵ it contains no �⌘-redexes.
14 / 45
�-reduction examples
1 (� x y . x y) (� z . z z)
2 !� (� y . (� z . z z) y)
3 !� (� y . y y)
15 / 45
�-reduction examples
An example in which ↵-conversion is needed:
1 (� x . (� y z . x z)) (� z . z)
2 !↵ (� x . (� y z . x z)) (� w . w)
3 !� (� y z . (� w . w) z)
4 !� (� y z . z)
16 / 45
�-reduction examples
An example that diverges:
1 (� x . x x) (� x . x x)
2 !� (� x . x x) (� x . x x)
3 !� ...
17 / 45
Unique normal forms
The Church-Rosser Theorem for � says that, if there is a normalform, then it is unique:
M
- -
- -
P Q
- -
- -
T
This is called the diamond property, or confluence.
18 / 45
�s for all
It’s not all theorems and greek letters. Hungry Alligators is a greatgame to teach the idea of functions to children.
http://worrydream.com/AlligatorEggs/
19 / 45
Evaluating �-terms
So, �⌘-reduction means evaluating a � expression.
But there are several choices we might make about how to dothat...although Church-Rosser means that if a NF exists we will getthere in the end, it will make a big di↵erence to intermediate forms.
Evaluation is from left to right, but we can use a call-by-name orcall-by-value approach.
20 / 45
Evaluation strategies
In call-by-name reduction, arguments are supplied to functions asthey are (i.e. without being evaluated). This is also called beingnon-strict or lazy.
In call-by-value reduction, arguments to functions are evaluatedbefore being supplied. This is also called a strict or eagerevaluation strategy.
21 / 45
EvaluationCall-by-name
1 (� y. (� x. x) y) ((� u. u) (� v. v))
2 !�⌘ (� x. x) ((� u. u) (� v. v))
3 !�⌘ ((� u. u) (� v. v))
4 !�⌘ (� v. v)
22 / 45
EvaluationCall-by-value
1 (� y. (� x. x) y) ((� u. u) (� v. v))
2 !�⌘ (� y. (� x. x) y) (� v. v)
3 !�⌘ (� x. x) (� v. v)
4 !�⌘ (� v. v)
23 / 45
Church encoding
So, what can we do with this?
This simple system can be used to compute anything. Aprogramming language built from the ground up with �C is calleda Church encoding.
�⌘-reduction is computation and a term in �⌘-nf is the result.
The idea is to express the behaviour of PL constructs in thestructure of �-terms.
24 / 45
Church encoding
First, we can express numbers by nesting �-terms – these are theChurch numerals.
The natural number n is a function that applies its first argumentn times to its second argument.
E.g. zero = �fy .y , one = �fy .f y , two = �fy .f (f y).
25 / 45
Church encoding
To make a successor function we just wrap another application off around the number and we can define arithmetic that way:
succ n f x ⌘ �nfx .f (n f x)
(remember that n is a function that takes two arguments...)
26 / 45
Church encoding
Let’s try it out:
1 succ zero = (� n f x . f (n f x)) zero #defn of
succ
2 ! (� n f x . f (n f x)) (� x y . y) #defn of zero
3 !�⌘ � f x . f ((� x y . y) f x)
4 !�⌘ (� f x . f ((� y . y) x))
5 !�⌘ (� f x . f x)
6 ⌘ one
27 / 45
Church encodingConditional branching
To make an expression if P then X else Y , we need an expressionthat returns X if P is “true”, and Y otherwise.
We can do this by modelling “true” as the expression that takestwo arguments and returns its first, and “false” as the expressionthat takes two arguments and returns its second.
28 / 45
Church encodingConditional branching
1 true ⌘ � x y . x
2 false ⌘ � x y . y
3 if ⌘ � p Y X . p X Y
29 / 45
Church encoding
Then we can write expressions like if x M N where x evaluates totrue or false and the whole expression evaluates to M or N.
We can make other logical operators, e.g. and will return true i↵both arguments evaluate to true:
1 and ⌘ � X Y . X Y X
How about or? not?
30 / 45
Church encoding
Then we can write expressions like if x M N where x evaluates totrue or false and the whole expression evaluates to M or N.
We can make other logical operators, e.g. and will return true i↵both arguments evaluate to true:
1 and ⌘ � X Y . X Y X
How about or? not?
30 / 45
Church encodingChurch pairs
Church pairs are tuples from which we can pull out the first andsecond element. x and y are the elements and the whole term iswaiting for a selector which will pick one of them...
1 pair ⌘ � x y z . z x y
2 fst ⌘ � p . p (� x y . x)
3 snd ⌘ � p . p (� x y . y)
31 / 45
Church encoding
So let’s make a pair:
1 mypair ⌘ (pair one) two
2 ! ((� x y z . z x y) one) two #defn of pair
3 !�⌘ (� y z . z one y) two
4 !�⌘ � z . z one two
And we can’t go any further (other than to unwrap ourconvenience identifiers one and two).
32 / 45
Church encoding
Let’s pick out the second element of the pair:
1 snd mypair ⌘ (� p . p (� x y . y)) mypair #defn of
snd
2 !�⌘ mypair (� x y . y)
3 ! (� z . z one two) (� x y . y) #defn of mypair
4 !�⌘ ((� x y . y) one) two
5 !�⌘ (� y . y) two
6 !�⌘ two
33 / 45
Church encoding
We can’t have a functional programming language without lists.
We can make a list as a pair where the first element is the head ofthe list and the second is the tail.
In order to cope with empty lists, we put the list as the secondelement in another pair, where the first element tells us whetherthe list is empty.
34 / 45
Church encoding
1 nil ⌘ (pair true) true #true in the first element
means empty
2 cons ⌘ � h t . (pair false) ((pair h) t)
3 head ⌘ � l . fst (snd l)
4 tail ⌘ � l . snd (snd l)
35 / 45
Church encoding
What we really need for this is a REPL.
There’s a very nice one available from zeroturnaround1. The REPLaccompanies a very nice tutorial on writing a parser, AST andinterpreter for a simple language (�C, but also any other) in Scala2.
Demo
1https://github.com/Villane/lambdacalculus
2http://zeroturnaround.com/rebellabs/
what-is-lambda-calculus-and-why-should-you-care/
36 / 45
Further reading
In Recursive Programming Techniques, Wm Burge develops alanguage with lispy semantics and Haskellish syntax from aground-up Church encoding. In 1975.
It’s a great read with some deep insights into the power of FP.
37 / 45
In conclusion
The power of the functional paradigm comes from its clarity andexpressiveness.
The clarity of functional languages (especially pure ones) isreflected in the �C as a simple model for evaluating functions.
The expressiveness is closely connected to higher-order functionsand an emphasis on recursion – the old chestnut about what ratherthan how – both of which come straight from this simple, elegantsystem.
38 / 45
In conclusion
Questions?
39 / 45
Extra
Some extra info and slightly more
formal versions of some definitions
etc.
40 / 45
The untyped �-CalculusNotation
An expression in �-C is made up of �-terms, which are one of thefollowing
1 atomic terms, x (we can think of these as variables too, if wehave some way of looking up their value)
2 applications, M N. There are no types, so we can supplyanything as the argument to a function.
3 abstractions, (�x .M) where x and M are �-terms. These areanonymous functions, like the lambdas in programminglanguages. The dot separates the argument from the body.The return value might be another lambda. Each abstractiontakes one argument and we can nest them.
41 / 45
� and ⌘ reduction, normal forms
�-reduction is function application. A �-redex is a term (�x .M)Nand we reduce it with the rewrite rule:
(�x .M)N
M[N/x ](�)
also written:
(�x .M)N !� M[N/x ]
42 / 45
Combinators
A closed term or combinator is one with no free variables. Someimportant combinators:
I (for identity – returns its argument) I ⌘ �x .x
K (for constant – when applied to its argument, x , gives aone-place function that returns x for any input) K ⌘ �xy .x
S (for substitution) S ⌘ �xyz .x z (y z)
S, K and I are Turing-complete!
43 / 45
Combinators
Another important one is Church’s fixed-point combinator,
Y ⌘ �x .(�y .x(y y))(�y .x(y y)).
The fixed point of a function, f , is an argument x such thatf (x) = x .
The Y-combinator has the property that Yf = f (Y f ) (applying Yto f produces the fixed point of f ) and is needed in order to writerecursive functions. It looks very abstract and mind-bending atfirst...nice explanation and derivation in The Why of Y, Richard PGabriel.
44 / 45
Simply-typed �C
�x .x x : There be dragons. Russell and Whitehead invented types
to rule out paradoxes like this.
Church developed a typed version of �C, but the type theory thateventually developed into the polymorphic type theories used byfunctional languages today is due to Haskell Curry.
The simplest version of this is called TA (type assignment). Addsimple types to �C and change the rules so that reduction has tobe well-typed.
45 / 45