the lambda calculus
DESCRIPTION
the lambda calculus. David Walker CS 441. 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. - PowerPoint PPT PresentationTRANSCRIPT
![Page 1: the lambda calculus](https://reader036.vdocuments.mx/reader036/viewer/2022062305/568160ed550346895dd022ab/html5/thumbnails/1.jpg)
the lambda calculus
David WalkerCS 441
![Page 2: the lambda calculus](https://reader036.vdocuments.mx/reader036/viewer/2022062305/568160ed550346895dd022ab/html5/thumbnails/2.jpg)
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”
![Page 3: the lambda calculus](https://reader036.vdocuments.mx/reader036/viewer/2022062305/568160ed550346895dd022ab/html5/thumbnails/3.jpg)
Reading
• Pierce, Chapter 5
![Page 4: the lambda calculus](https://reader036.vdocuments.mx/reader036/viewer/2022062305/568160ed550346895dd022ab/html5/thumbnails/4.jpg)
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
![Page 5: the lambda calculus](https://reader036.vdocuments.mx/reader036/viewer/2022062305/568160ed550346895dd022ab/html5/thumbnails/5.jpg)
syntax
t,e ::= x (a variable) | \x.e (a function; in ML: fn x =>
e) | e e (function application)
![Page 6: the lambda calculus](https://reader036.vdocuments.mx/reader036/viewer/2022062305/568160ed550346895dd022ab/html5/thumbnails/6.jpg)
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))”
![Page 7: the lambda calculus](https://reader036.vdocuments.mx/reader036/viewer/2022062305/568160ed550346895dd022ab/html5/thumbnails/7.jpg)
terminology
• \x.t
• \x.x y
the scope of x is the term t
x is boundin the term \x.x y
y is free in the term \x.x y
![Page 8: the lambda calculus](https://reader036.vdocuments.mx/reader036/viewer/2022062305/568160ed550346895dd022ab/html5/thumbnails/8.jpg)
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]
![Page 9: the lambda calculus](https://reader036.vdocuments.mx/reader036/viewer/2022062305/568160ed550346895dd022ab/html5/thumbnails/9.jpg)
operational semantics
• search rules:
• notice, evaluation is left to right
e1 --> e1’e1 e2 --> e1’ e2
e2 --> e2’v e2 --> v e2’
![Page 10: the lambda calculus](https://reader036.vdocuments.mx/reader036/viewer/2022062305/568160ed550346895dd022ab/html5/thumbnails/10.jpg)
Example
(\x. x x) (\y. y)
![Page 11: the lambda calculus](https://reader036.vdocuments.mx/reader036/viewer/2022062305/568160ed550346895dd022ab/html5/thumbnails/11.jpg)
Example
(\x. x x) (\y. y)--> x x [\y. y / x]
![Page 12: the lambda calculus](https://reader036.vdocuments.mx/reader036/viewer/2022062305/568160ed550346895dd022ab/html5/thumbnails/12.jpg)
Example
(\x. x x) (\y. y)--> x x [\y. y / x]== (\y. y) (\y. y)
![Page 13: the lambda calculus](https://reader036.vdocuments.mx/reader036/viewer/2022062305/568160ed550346895dd022ab/html5/thumbnails/13.jpg)
Example
(\x. x x) (\y. y)--> x x [\y. y / x]== (\y. y) (\y. y)--> y [\y. y / y]
![Page 14: the lambda calculus](https://reader036.vdocuments.mx/reader036/viewer/2022062305/568160ed550346895dd022ab/html5/thumbnails/14.jpg)
Example
(\x. x x) (\y. y)--> x x [\y. y / x]== (\y. y) (\y. y)--> y [\y. y / y]== \y. y
![Page 15: the lambda calculus](https://reader036.vdocuments.mx/reader036/viewer/2022062305/568160ed550346895dd022ab/html5/thumbnails/15.jpg)
Another example
(\x. x x) (\x. x x)
![Page 16: the lambda calculus](https://reader036.vdocuments.mx/reader036/viewer/2022062305/568160ed550346895dd022ab/html5/thumbnails/16.jpg)
Another example
(\x. x x) (\x. x x)--> x x [\x. x x/x]
![Page 17: the lambda calculus](https://reader036.vdocuments.mx/reader036/viewer/2022062305/568160ed550346895dd022ab/html5/thumbnails/17.jpg)
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?
![Page 18: the lambda calculus](https://reader036.vdocuments.mx/reader036/viewer/2022062305/568160ed550346895dd022ab/html5/thumbnails/18.jpg)
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
![Page 19: the lambda calculus](https://reader036.vdocuments.mx/reader036/viewer/2022062305/568160ed550346895dd022ab/html5/thumbnails/19.jpg)
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
target = lambda calculus
translate/compile
![Page 20: the lambda calculus](https://reader036.vdocuments.mx/reader036/viewer/2022062305/568160ed550346895dd022ab/html5/thumbnails/20.jpg)
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
![Page 21: the lambda calculus](https://reader036.vdocuments.mx/reader036/viewer/2022062305/568160ed550346895dd022ab/html5/thumbnails/21.jpg)
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)
![Page 22: the lambda calculus](https://reader036.vdocuments.mx/reader036/viewer/2022062305/568160ed550346895dd022ab/html5/thumbnails/22.jpg)
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) = xtranslate (\x.e) = \x.translate etranslate (e1 e2) = (translate e1) (translate e2)
![Page 23: the lambda calculus](https://reader036.vdocuments.mx/reader036/viewer/2022062305/568160ed550346895dd022ab/html5/thumbnails/23.jpg)
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
![Page 24: the lambda calculus](https://reader036.vdocuments.mx/reader036/viewer/2022062305/568160ed550346895dd022ab/html5/thumbnails/24.jpg)
booleans
• the encoding:
tru = \t.\f. t
fls = \t.\f. f
test = \x.\then.\else. x then else
![Page 25: the lambda calculus](https://reader036.vdocuments.mx/reader036/viewer/2022062305/568160ed550346895dd022ab/html5/thumbnails/25.jpg)
booleans
tru = \t.\f. t fls = \t.\f. ftest = \x.\then.\else. x then else
eg:
test tru (\x.t1) (\x.t2) -->* (\t.\f. t) (\x.t1) (\x.t2) -->* \x.t1
![Page 26: the lambda calculus](https://reader036.vdocuments.mx/reader036/viewer/2022062305/568160ed550346895dd022ab/html5/thumbnails/26.jpg)
booleans
tru = \t.\f. t fls = \t.\f. fand = \b.\c. b c fls
and tru tru -->* tru tru fls -->* tru
![Page 27: the lambda calculus](https://reader036.vdocuments.mx/reader036/viewer/2022062305/568160ed550346895dd022ab/html5/thumbnails/27.jpg)
booleans
tru = \t.\f. t fls = \t.\f. fand = \b.\c. b c fls
and fls tru -->* fls tru fls -->* fls
![Page 28: the lambda calculus](https://reader036.vdocuments.mx/reader036/viewer/2022062305/568160ed550346895dd022ab/html5/thumbnails/28.jpg)
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)...
![Page 29: the lambda calculus](https://reader036.vdocuments.mx/reader036/viewer/2022062305/568160ed550346895dd022ab/html5/thumbnails/29.jpg)
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 regardlessof whether e1 is true or false-- the target program might not terminate in some cases when the source program would
![Page 30: the lambda calculus](https://reader036.vdocuments.mx/reader036/viewer/2022062305/568160ed550346895dd022ab/html5/thumbnails/30.jpg)
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
![Page 31: the lambda calculus](https://reader036.vdocuments.mx/reader036/viewer/2022062305/568160ed550346895dd022ab/html5/thumbnails/31.jpg)
pairs
create = \fst.\sec.\bool. bool fst secfst = \p. p trusec = \p. p fls
fst (create tru fls)-->* fst (\bool. bool tru fls)-->* (\bool. bool tru fls) tru-->* tru
![Page 32: the lambda calculus](https://reader036.vdocuments.mx/reader036/viewer/2022062305/568160ed550346895dd022ab/html5/thumbnails/32.jpg)
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
![Page 33: the lambda calculus](https://reader036.vdocuments.mx/reader036/viewer/2022062305/568160ed550346895dd022ab/html5/thumbnails/33.jpg)
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]
![Page 34: the lambda calculus](https://reader036.vdocuments.mx/reader036/viewer/2022062305/568160ed550346895dd022ab/html5/thumbnails/34.jpg)
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])
![Page 35: the lambda calculus](https://reader036.vdocuments.mx/reader036/viewer/2022062305/568160ed550346895dd022ab/html5/thumbnails/35.jpg)
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
![Page 36: the lambda calculus](https://reader036.vdocuments.mx/reader036/viewer/2022062305/568160ed550346895dd022ab/html5/thumbnails/36.jpg)
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!
![Page 37: the lambda calculus](https://reader036.vdocuments.mx/reader036/viewer/2022062305/568160ed550346895dd022ab/html5/thumbnails/37.jpg)
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)
![Page 38: the lambda calculus](https://reader036.vdocuments.mx/reader036/viewer/2022062305/568160ed550346895dd022ab/html5/thumbnails/38.jpg)
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])
![Page 39: the lambda calculus](https://reader036.vdocuments.mx/reader036/viewer/2022062305/568160ed550346895dd022ab/html5/thumbnails/39.jpg)
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))
![Page 40: the lambda calculus](https://reader036.vdocuments.mx/reader036/viewer/2022062305/568160ed550346895dd022ab/html5/thumbnails/40.jpg)
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
![Page 41: the lambda calculus](https://reader036.vdocuments.mx/reader036/viewer/2022062305/568160ed550346895dd022ab/html5/thumbnails/41.jpg)
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
![Page 42: the lambda calculus](https://reader036.vdocuments.mx/reader036/viewer/2022062305/568160ed550346895dd022ab/html5/thumbnails/42.jpg)
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 likeso this is true.
![Page 43: the lambda calculus](https://reader036.vdocuments.mx/reader036/viewer/2022062305/568160ed550346895dd022ab/html5/thumbnails/43.jpg)
operational semantics again
• Is this the only possible operational semantics?
e1 --> e1’e1 e2 --> e1’ e2
e2 --> e2’v e2 --> v e2’
(\x.t) v --> t [v/x]
![Page 44: the lambda calculus](https://reader036.vdocuments.mx/reader036/viewer/2022062305/568160ed550346895dd022ab/html5/thumbnails/44.jpg)
alternatives
e1 --> e1’e1 e2 --> e1’ e2
e2 --> e2’v e2 --> v e2’
(\x.t) v --> t [v/x]
e1 --> e1’e1 e2 --> e1’ e2
(\x.t) e --> t [e/x]
call-by-value call-by-name
![Page 45: the lambda calculus](https://reader036.vdocuments.mx/reader036/viewer/2022062305/568160ed550346895dd022ab/html5/thumbnails/45.jpg)
alternatives
e1 --> e1’e1 e2 --> e1’ e2
e2 --> e2’v e2 --> v e2’
(\x.t) v --> t [v/x]
e1 --> e1’e1 e2 --> e1’ e2
(\x.t) e --> t [e/x]
call-by-value full beta-reduction
e2 --> e2’e1 e2 --> e1 e2’
e --> e’\x.e --> \x.e’
![Page 46: the lambda calculus](https://reader036.vdocuments.mx/reader036/viewer/2022062305/568160ed550346895dd022ab/html5/thumbnails/46.jpg)
alternatives
e1 --> e1’e1 e2 --> e1’ e2
e2 --> e2’v e2 --> v e2’
(\x.t) v --> t [v/x]
e1 --> e1’ e1 ≠ ve1 e2 --> e1’ e2
(\x.t) e --> t [e/x]
call-by-value normal-order reduction
e2 --> e2’v e2 --> v e2’
e --> e’\x.e --> \x.e’
![Page 47: the lambda calculus](https://reader036.vdocuments.mx/reader036/viewer/2022062305/568160ed550346895dd022ab/html5/thumbnails/47.jpg)
alternatives
e1 --> e1’e1 e2 --> e1’ e2
e2 --> e2’v e2 --> v e2’
(\x.t) v --> t [v/x]
call-by-value right-to-left call-by-value
e1 --> e1’e1 v --> e1’ v
e2 --> e2’e1 e2 --> e1 e2’
(\x.t) v --> t [v/x]
![Page 48: the lambda calculus](https://reader036.vdocuments.mx/reader036/viewer/2022062305/568160ed550346895dd022ab/html5/thumbnails/48.jpg)
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