the lambda calculus

1 / 48

# the lambda calculus - PowerPoint PPT Presentation

the lambda calculus. David Walker CS 510. the lambda calculus. Originally, the lambda calculus was developed as a logic by Alonzo Church in 1932 Church says: “There may, indeed, be other applications of the system than its use as a logic.” Dave says: “I’ll say”. Reading.

I am the owner, or an agent authorized to act on behalf of the owner, of the copyrighted work described.

## the lambda calculus

Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author.While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server.

- - - - - - - - - - - - - - - - - - - - - - - - - - E N D - - - - - - - - - - - - - - - - - - - - - - - - - -
Presentation Transcript

### the lambda calculus

David Walker

CS 510

the lambda calculus
• Originally, the lambda calculus was developed as a logic by Alonzo Church in 1932
• Church says: “There may, indeed, be other applications of the system than its use as a logic.”
• Dave says: “I’ll say”
• Pierce, Chapter 5
functions
• essentially every full-scale programming language has some notion of function
• the (pure) lambda calculus is a language composed entirely of functions
• we use the lambda calculus to study the essence of computation
• it is just as fundamental as Turing Machines
syntax

t,e ::= x (a variable)

| \x.e (a function; in ML: fn x => e)

| e e (function application)

syntax
• the identity function:
• \x.x
• 2 notational conventions:
• applications associate to the left (like in ML):
• “y z x” is “(y z) x”
• the body of a lambda extends as far as possible to the right:
• “\x.x \z.x z x” is “\x.(x \z.(x z x))”
terminology
• \x.t
• \x.x y

the scope of x is the term t

y is free in the term \x.x y

x is bound

in the term \x.x y

CBV operational semantics
• single-step, call-by-value OS: t --> t’
• values are v ::= \x.t
• primary rule (beta reduction):
• t [v/x] is the term in which all free occurrences of x in t are replaced with v
• this replacement operation is called substitution
• we will define it carefully later in the lecture

(\x.t) v --> t [v/x]

operational semantics
• search rules:
• notice, evaluation is left to right

e1 --> e1’

e1 e2 --> e1’ e2

e2 --> e2’

v e2 --> v e2’

Example

(\x. x x) (\y. y)

Example

(\x. x x) (\y. y)

--> x x [\y. y / x]

Example

(\x. x x) (\y. y)

--> x x [\y. y / x]

== (\y. y) (\y. y)

Example

(\x. x x) (\y. y)

--> x x [\y. y / x]

== (\y. y) (\y. y)

--> y [\y. y / y]

Example

(\x. x x) (\y. y)

--> x x [\y. y / x]

== (\y. y) (\y. y)

--> y [\y. y / y]

== \y. y

Another example

(\x. x x) (\x. x x)

Another example

(\x. x x) (\x. x x)

--> x x [\x. x x/x]

Another example

(\x. x x) (\x. x x)

--> x x [\x. x x/x]

== (\x. x x) (\x. x x)

• In other words, it is simple to write non terminating computations in the lambda calculus
• what else can we do?
We can do everything
• The lambda calculus can be used as an “assembly language”
• We can show how to compile useful, high-level operations and language features into the lambda calculus
• Result = adding high-level operations is convenient for programmers, but not a computational necessity
• Result = make your compiler intermediate language simpler
Let Expressions
• It is useful to bind intermediate results of computations to variables:

let x = e1 in e2

• Question: can we implement this idea in the lambda calculus?

source = lambda calculus + let

translate/compile

target = lambda calculus

Let Expressions
• It is useful to bind intermediate results of computations to variables:

let x = e1 in e2

• Question: can we implement this idea in the lambda calculus?

translate (let x = e1 in e2) =

(\x.e2) e1

Let Expressions
• It is useful to bind intermediate results of computations to variables:

let x = e1 in e2

• Question: can we implement this idea in the lambda calculus?

translate (let x = e1 in e2) =

(\x. translate e2) (translate e1)

Let Expressions
• It is useful to bind intermediate results of computations to variables:

let x = e1 in e2

• Question: can we implement this idea in the lambda calculus?

translate (let x = e1 in e2) =

(\x. translate e2) (translate e1)

translate (x) = x

translate (\x.e) = \x.translate e

translate (e1 e2) = (translate e1) (translate e2)

booleans
• we can encode booleans
• we will represent “true” and “false” as functions named “tru” and “fls”
• how do we define these functions?
• think about how “true” and “false” can be used
• they can be used by a testing function:
• “test b then else” returns “then” if b is true and returns “else” if b is false
• the only thing the implementation of test is going to be able to do with b is to apply it
• the functions “tru” and “fls” must distinguish themselves when they are applied
booleans
• the encoding:

tru = \t.\f. t

fls = \t.\f. f

test = \x.\then.\else. x then else

booleans

tru = \t.\f. t fls = \t.\f. f

test = \x.\then.\else. x then else

eg:

test tru (\x.t1) (\x.t2)

-->* (\t.\f. t) (\x.t1) (\x.t2)

-->* \x.t1

booleans

tru = \t.\f. t fls = \t.\f. f

and = \b.\c. b c fls

and tru tru

-->* tru tru fls

-->* tru

booleans

tru = \t.\f. t fls = \t.\f. f

and = \b.\c. b c fls

and fls tru

-->* fls tru fls

-->* fls

booleans
• what is wrong with the following translation?

translate true = tru

translate false = fls

translate (if e1 then e2 else e3)

= test (translate e1) (translate e2) (translate e3)

...

booleans
• what is wrong with the following translation?

translate true = tru

translate false = fls

translate (if e1 then e2 else e3)

= test (translate e1) (translate e2) (translate e3)

...

-- e2 and e3 will both be evaluated regardless

of whether e1 is true or false

-- the target program might not terminate

in some cases when the source program would

pairs
• would like to encode the operations
• create e1 e2
• fst p
• sec p
• pairs will be functions
• when the function is used in the fst or sec operation it should reveal its first or second component respectively
pairs

create = \fst.\sec.\bool. bool fst sec

fst = \p. p tru

sec = \p. p fls

fst (create tru fls)

-->* fst (\bool. bool tru fls)

-->* (\bool. bool tru fls) tru

-->* tru

and we can go on...
• numbers
• arithmetic expressions (+, -, *,...)
• lists, trees and datatypes
• exceptions, loops, ...
• ...
• the general trick:
• values will be functions – construct these functions so that they return the appropriate information when called by an operation
Formal details
• In order to be precise about the operational semantics of the lambda calculus, we need to define substitution properly
• remember the primary evaluation rule:

(\x.t) v --> t [v/x]

substitution: a first try
• the definition is given inductively:

x [t/x] = t

y [t/x] = y (if y ≠ x)

(\y.t’) [t/x] = \y.t’ [t/x]

t1 t2 [t/x] = (t1 [t/x]) (t2 [t/x])

substitution: a first try
• This works well 50% of the time
• Fails miserably the rest of the time:

(\x. x) [y/x] = \x. y

• the x in the body of (\x. x) refers to the argument of the function
• a substitution should not replace the x
• we got “unlucky” with our choice of variable names
substitution: a first try
• This works well 50% of the time
• Fails miserably the rest of the time:

(\x. z) [x/z] = \x. x

• the z in the body of (\x. z) does not refer to the argument of the function
• after substitution, it does refer to the argument
• we got “unlucky” with our choice of variable names again!
calculating free variables
• To define substitution properly, we must be able to calculate the free variables precisely:

FV(x) = {x}

FV(\x.t) = FV(t) / {x}

FV(t1 t2) = FV(t1) U FV(t2)

substitution

x [t/x] = t y [t/x] = y (if y ≠ x)

(\y.t’) [t/x] = \y.t’ (if y = x)

(\y.t’) [t/x] = \y.t’ [t/x] (if y ≠ x and y  FV(t))

t1 t2 [t/x] = (t1 [t/x]) (t2 [t/x])

substitution
• almost! But the definition is not exhaustive
• what if y ≠ x and y  FV(t) in the case for functions:

(\y.t’) [t/x] = \y.t’ (if y = x)

(\y.t’) [t/x] = \y.t’ [t/x] (if y ≠ x and y  FV(t))

alpha conversion
• the names of bound variables are unimportant (as far as the meaning of the computation goes)
• in ML, there is no difference between
• fn x => x and fn y => y
• we will treat \x. x and \y. y as if they are (absolutely and totally) indistinguishable so we can always use one in place of the other
alpha conversion
• in general, we will adopt the convention that terms that differ only in the names of bound variables are interchangeable
• ie: \x.t == \y. t[y/x] (where this is the latest version of substitution)
• changing the name of a bound variable is called alpha conversion
substitution, finally

x [t/x] = t y [t/x] = y (if y ≠ x)

(\y.t’) [t/x] = \y.t’ [t/x] (if y ≠ x and y  FV(t))

t1 t2 [t/x] = (t1 [t/x]) (t2 [t/x])

we use alpha-equivalent terms so

this constraint can always be

satisfied. We pick y as we like

so this is true.

operational semantics again
• Is this the only possible operational semantics?

(\x.t) v --> t [v/x]

e1 --> e1’

e1 e2 --> e1’ e2

e2 --> e2’

v e2 --> v e2’

alternatives

(\x.t) e --> t [e/x]

(\x.t) v --> t [v/x]

e1 --> e1’

e1 e2 --> e1’ e2

e1 --> e1’

e1 e2 --> e1’ e2

e2 --> e2’

v e2 --> v e2’

call-by-value

call-by-name

alternatives

(\x.t) e --> t [e/x]

(\x.t) v --> t [v/x]

e1 --> e1’

e1 e2 --> e1’ e2

e1 --> e1’

e1 e2 --> e1’ e2

e2 --> e2’

e1 e2 --> e1 e2’

e2 --> e2’

v e2 --> v e2’

e --> e’

\x.e --> \x.e’

call-by-value

full beta-reduction

alternatives

(\x.t) e --> t [e/x]

(\x.t) v --> t [v/x]

e1 --> e1’ e1 ≠ v

e1 e2 --> e1’ e2

e1 --> e1’

e1 e2 --> e1’ e2

e2 --> e2’

v e2 --> v e2’

e2 --> e2’

v e2 --> v e2’

e --> e’

\x.e --> \x.e’

call-by-value

normal-order reduction

alternatives

(\x.t) v --> t [v/x]

(\x.t) v --> t [v/x]

e1 --> e1’

e1 e2 --> e1’ e2

e1 --> e1’

e1 v --> e1’ v

e2 --> e2’

v e2 --> v e2’

e2 --> e2’

e1 e2 --> e1 e2’

call-by-value

right-to-left call-by-value

summary
• the lambda calculus is a language of functions
• Turing complete
• easy to encode many high-level language features
• the operational semantics
• primary rule: beta-reduction
• depends upon careful definition of substitution
• many evaluation strategies