0% found this document useful (0 votes)
7 views

Semantics of Programming Languages Lecture 8

Uploaded by

M
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
7 views

Semantics of Programming Languages Lecture 8

Uploaded by

M
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 13

Functions as data

Matthew Hennessy

April 2, 2015

Lambda Matthew Hennessy

Notation for functions

Anonymous functions

I λx .x + 3 - from numerals to numerals

I λf .f (2) - from functions to numerals

I λx .if x = 0 then λy .y else λy .x - from numerals to


functions

I λf .λx .if x = 0 then 1 else (let y = f (x − 1) in x × y ) -


from functions to functions

I λf .λg . λx .f (g (x)) - from pairs of functions to functions

Lambda Matthew Hennessy


The Lambda-calculus

M ∈ Lambda ::= v
| M1 + M2
| M1 and M2 | M1 or M2 | M1 = M2 | M1 < M2
| if M1 then M2 else M2
| let x = M1 in M3
| M1 M2
v ∈ Val ::= x ∈ Vars | n ∈ Nums | tt | ff | λx .M

I M1 M2 : apply function M1 to M2 or App(M1 , M2 )


I λx .M: anonymous function which when applied to data N
executes M{|N/x |}

Lambda Matthew Hennessy

Free variables

I fv(x) = {x} fv(n) = fv(tt) = fv(ff) = {}


I fv(M1 op M2 ) = fv(M1 ) ∪ fv(M2 )
I fv(M1 M2 ) = fv(M1 ) ∪ fv(M2 )
I fv(let y = M1 in M2 ) = fv(M1 ) ∪ (fv(M2 ) − {y })
I fv(λx .M) = fv(M) − {x}

Closed terms:
M is closed if fv(M) = {}
Closed terms correspond to programs

Lambda Matthew Hennessy


Small-step semantics

Judgements:

M →N
where M, N are programs

Intuition:
M performs
I one function application
I or one built-in operation
and N remains to be evaluated

Lambda Matthew Hennessy

Semantic rules

Standard rules:
(s-left)
M1 → M10
(M1 + M2 ) → (M10 + M2 )
(s-right)
M2 → M20
(n1 + M2 ) → (n1 + M20 )
(s-add)

n3 = add(n1 , n1 )
(n1 + n2 ) → n3

Similar rules for or and, if then else . . .

Lambda Matthew Hennessy


Semantic rules

To evaluate let x = M in E
I Keep evaluating M to obtain a value v.
I Then substitute v in for x in E and continue evaluating

(s-let)
M → M0
(1)
let x = M in E → let x = M 0 in E
(s-let.subs)
(2)
let x = v in E → E {|v/x |}

Lambda Matthew Hennessy

Function application

To evaluate M1 M2 :
I evaluate M1 to a function λx .M

Call-by-value\eager: Call-by-name\lazy:
I evaluate M2 to a value v I evaluate M{|M2/x |}
I evaluate M{|v/x |}

v ∈ Val ::= n | tt | ff | λx .N

Lambda Matthew Hennessy


Function application
(l-app)
M1 →e M10
M1 M2 →e M10 M2

Call-by-value\eager:
(l-cbv.a) (l-cbv)
M2 →e M20
(λx .M)M2 →e (λx .M)M20 (λx .M)v →e M{|v/x |}

Values:
v ∈ Val ::= n | tt | ff | λx .N

Lambda Matthew Hennessy

Function application
(l-app)
M1 →l M10
M1 M2 →l M10 M2

Call-by-name\lazy:
(l-cbn)

(λx .M)M2 →l M{|M2/x |}

Note:
M2 is a closed term

Lambda Matthew Hennessy


Substitution of closed terms
N closed:
I x{|N/x |} = N
I y {|N/x |} = y y 6= x
I (λx .M){|N/x |} = λx .M
I (λy .M){|N/x |} = λy .(M{|N/x |})
I (M1 M2 ){|N/x |} = (M1 {|N/x |})(M2 {|N/x |})
I (M1 op M2 ){|N/x |} = (M1 {|N/x |}) op (M2 {|N/x |})
I .........

N open:
Not defined

Lambda Matthew Hennessy

Self-application eager and lazy semantics

∆ , λx .x x

∆∆ → ∆∆ → ∆∆ → . . . . . . ∆∆ → . . . . . .

Non-termination is built-in to Lambda

Lambda Matthew Hennessy


Eager v. lazy

They give different results:

I (λx .0)(∆∆) →l 0
I (λx .0)(∆∆) →e . . . →e . . . →e . . .

I (λx .λy .x) (Id 0) →∗e λy .0


I (λx .λy .x) (Id 0) →∗l λy .(Id 0)
See Pierce pp. 56 for different evaluation strategies

Lazy very inefficient a priori

(λx .x + x + x) M →l M + M + M

Lambda Matthew Hennessy

Fixpoints via Turings combinator

A ,λx .λy .y (xxy )


Θ ,A A
For any program P: lazy

Θ P →l (λy .y (AAy ))P


→l P(ΘP)

Choose P of form λf .λx .B:


Θ (λf .λx .B) →∗l (λf .λx .B) (Θ λf .λx .B)
→l λx .B{|Θ (λf .λx .B)
/f |}

With Θ recursive functions can be defined.


Lambda Matthew Hennessy
Fixpoints
For any program P: Θ P →l (λy .y (AAy ))P
→l P(ΘP)

Θ (λf .λx .B) →∗l (λf .λx .B) (Θ λf .λx .B)


→l λx .B{|Θ (λf .λx .B)
/f |}

Recursive definitions:

recf .B abbreviation for Θ (λf .λx .B)

recf .B →∗l λx .B{|recf .B/f |}

Lambda Matthew Hennessy

Example: the factorial function


.
λf .λx .if x = 0 then 1 else x × f (x − 1)
= λf .λx .F
recf .F = recursive definition of factorial
.
recf .F →∗l λx .if x = 0 then 1 else x × (recf .F ) (x − 1)

(recf .F ) 3
→∗l (λx .if x = 0 then 1 else x × (recf .F ) (x − 1)) 3
→∗l 3 × (recf .F ) 2
→∗l 3 × (λx .if x = 0 then 1 else x × (recf .F ) (x − 1)) 2
→∗l 3 × 2 × (recf .F ) 1
→∗l 3 × 2 × 1 × (recf .F ) 0
→∗l 3 × 2 × 1 × 1
→∗l 6
Lambda Matthew Hennessy
Fixpoints in the eager operational semantics

A ,λx .λy .y (xxy ) Θ,AA


For any program P: eager

Θ P →e (λy .y (AAy ))P A is a value


→e P(ΘP) if P is a value

Choose P of form λf .λx .B: a value

Θ (λf .λx .B) →∗e (λf .λx .B) (Θ λf .λx .B)


→l λx .B{|Θ (λf .λx .B)
/f |}
6→e λx .B{|Θ (λf .λx .B)
/f |}
(Θ λf .λx .B) is not a value
Lambda Matthew Hennessy

Eager evaluation of fixpoints

Θ (λf .λx .B) →∗e (λf .λx .B) (Θ λf .λx .B)


→∗e (λf .λx .B)(λf .λx .B) (Θ λf .λx .B)
→∗e (λf .λx .B)(λf .λx .B)(λf .λx .B) (Θ λf .λx .B)
→∗e . . . . . . forever

Solution we need to stop the indefinite unfolding of (Θ (λf .λx .B))

Lambda Matthew Hennessy


η-expansion

What is the difference between

Q λz .Q z? z not free in Q

Not much

(Θ (λf .λx .B) vs λz .(Θ (λf .λx .B)) z

One is a value, the other is not

Lambda Matthew Hennessy

Eager fixpoints

Late combinator:

A ,λx .λy .y (xxy ) Θ,AA

Early combinator:

Av ,λx .λy .y λz .(xxy )z Θv , Av Av

For any program P:

Θv P →e (λy .y λz .(Av Av y )z) P


→e P λz .(Θv P)z
Lazy: Θ P →l P (Θ P)

Lambda Matthew Hennessy


Eager recursive functions

recv f .B abbreviation for Θv (λf .λx .B)

recv f .B →∗e λf .λx .B) λz .recv f .B z


→∗e λx .B{|λz .(recv f .B) z/f |}

recv f .B v →∗e B{|λz .(recv f .B) z/f |} {|v/x |}

Lambda Matthew Hennessy

Example: the factorial function


.
λf .λx .if x = 0 then 1 else x × f (x − 1)
= λf .λx .F
recv f .F = recursive definition of factorial

recv f .F →∗e λx .if x = 0 then 1 else


.
x × (λz .recv f .F z) (x − 1)

(recv f .F ) 3
→∗e (λx .if x = 0 then 1 else x × (λz .recv f .F z) (x − 1)) 3
→∗e 3 × (λz .recv f .F z) 2
→∗e 3 × (recv f .F ) 2
→∗ . . .
Lambda Matthew Hennessy
The Lambda-calculus

M ∈ Lambda ::= v | M1 + M2
| M1 and M2 | M1 or M2 | M1 = M2 | M1 < M2
| if M1 then M2 else M2
| let x = M1 in M3
| M1 M2
v ∈ Val ::= x ∈ Vars | n ∈ Nums | tt | ff | λx .M

Equivalent:
M ∈ Lambda ::= x ∈ Vars | n ∈ Nums | λx .M
| M1 + 1 | Eq0 | M1 M2

Lambda Matthew Hennessy

The Lambda-calculus

M ∈ Lambda ::= x ∈ Vars | n ∈ Nums | λx .M


| M1 + 1 | Eq0 | M1 M2

Equivalent:

M ∈ Lambda ::= x ∈ Vars | λx .M | M1 M2

Arithmetic implemented using Church numbers

Lambda Matthew Hennessy


Church numbers

0 = λf .λx .x 1 = λf .λx .f x 2 = λf .λx .f (f x) . . .


n = λf .λx .f n x

Succ = λn .λf .λx .f (n f x)

Succ 1 = λf .λx .f (1 f x)
= 2 = λf .λx .f (f x) up to some theory

Eq0 : λn .n (λx .False) True


Eq0 0 →∗ True Eq0 1 →∗ False Eq0 2 →∗ False . . .

Lambda Matthew Hennessy

The Lambda-calculus

M ∈ Lambda ::= x ∈ Vars | λx .M | M1 M2

As a programming language:

I eager evaluation strategy


I lazy evaluation strategy

As a mathematical theory:

I Allow arbitrary reductions of redexes

Lambda Matthew Hennessy

You might also like