lambda demystified: into the heart of functional...

Post on 23-Jul-2020

3 Views

Category:

Documents

0 Downloads

Preview:

Click to see full reader

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

top related