Xavier Leroy - Semantics
Xavier Leroy - Semantics
Xavier Leroy
INRIA Paris-Rocquencourt
Various answers:
By examples: Caml, Haskell, Scheme, SML, . . .
“A language that takes functions seriously”.
A language that manipulates functions with free variables as
first-class values, following (more or less) the model of the λ-calculus.
Example 1
let rec map f lst =
match lst with [] -> [] | hd :: tl -> f hd :: map f tl
λ-calculus, recap
Terms: a, b ::= x | λx.a | a b
In this lecture:
1 Reduction strategies
Example of reduction
(λx.x) 1 → x[x ← 1] = 1
(app-r)
(λx.λy . y x) ((λx.x) 1) → (λx.λy . y x) 1
(app-l)
(λx.λy . y x) ((λx.x) 1) (λx.x) → (λx.λy . y x) 1 (λx.x)
Weak reduction:
We cannot reduce under a λ-abstraction.
a → a0
λx.a → λx.a0
Call-by-value:
In an application (λx.a) b, the argument b must be fully reduced to a
value before β-reduction can take place.
Left-to-right:
In an application a b, we must reduce a to a value first before we can
start reducing b.
b → b0
v b → v b0
(Right-to-left is equally acceptable and equally easy to specify.)
Deterministic:
For every term a, there is at most one a0 such that a → a0 .
(Since values cannot reduce, there is at most one rule among (βv ),
(app-l) and (app-r) that applies to a given term.)
Reduction sequences
Terminating:
Error: (λx. x x) 2 → 2 2 6→
(λx.x) 1 → 1
(app-r)
(λx.λy . y x) ((λx.x) 1) → (λx.λy . y x) 1
(app-l)
(λx.λy . y x) ((λx.x) 1) (λx.x) → (λx.λy . y x) 1 (λx.x)
Theorem 2
For all terms a, there exists at most one reduction context E and one term
b such that a = E [b] and b can reduce by head reduction.
(Exercise.)
Call-by-name
Unlike call-by-value, call-by-name does not evaluate arguments before
performing β-reduction. Instead, it performs β-reduction as soon as
possible; the argument will be reduced later when its value is needed in the
function body.
In SOS style:
a → a0
(λx.a) b → a[x ← b] (βn ) (app-l)
a b → a0 b
In Felleisen style:
ε
(λx.a) b → a[x ← b] with reduction contexts E ::= [ ] | E b
or in other words, E ::= [ ] b1 . . . bn
Outline
1 Reduction strategies
Example
The Caml expression
can be expressed as
λx. λlst.
(µmap. λf. λlst.
match lst with Nil() → Nil()
| Cons(hd, tl) → Cons(f hd, map f tl))
(λy. x + y) lst
let x = a in b 7→ (λx.b) a
(a, b) 7→ Pair(a, b)
fst(a) 7→ match a with Pair(x, y ) → x
snd(a) 7→ match a with Pair(x, y ) → y
Reduction rules
Head reductions:
ε
N 1 + N2 → N if N = N1 + N2
ε
N1 < N2 → true() if N1 < N2
ε
N1 < N2 → false() if N1 ≥ N2
ε
match C (~v ) with C (~x ) → a | p~ → a[~x ← ~v ] if |~v | = |~x |
0 ε
match C (~v ) with C (~x ) → a | p~ → match C (~v ) with p~ if C 6= C 0
ε
(µf .λx.a) v → a[f ← µf .λx.a, x ← v ]
Contexts:
E ::= . . . | E op a | v op E | C (~v , E , ~a) | match E with p~
ε
let x = v in a → a[x ← v ]
ε
if true then a else b → a
ε
if false then a else b → b
ε
fst(v1 , v2 ) → v1
ε
snd(v1 , v2 ) → v2
Outline
1 Reduction strategies
type term =
Const of int | Var of string | Lam of string * term | App of term * term
let isvalue = function Const _ -> true | Lam _ -> true | _ -> false
Algorithmic inefficiencies
a ⇒ λx.c c[x ← b] ⇒ v
ab⇒v
λx.x ⇒ λx.x
1⇒1
λx.x ⇒ λx.x
1⇒1
λx.λy .y x λy .y 1 1⇒1
⇒ λx.λy .y x (λx.x) 1 ⇒ 1 ⇒ λy .y 1 1⇒1
(λx.λy .y x) ((λx.x) 1) ⇒ λy .y 1 λx.x ⇒ λx.x (λx.x) 1 ⇒ 1
(λx.λy .y x) ((λx.x) 1) (λx.x) ⇒ 1
exception Error
Proof.
By induction on the derivation of a ⇒ v and case analysis on a.
If a = n or a = λx.b, then v = a and the result is obvious.
If a = b c, applying the induction hypothesis to the premises of b c ⇒ v ,
we obtain three reduction sequences:
∗ ∗ ∗
b → λx.d c → v0 d[x ← v 0 ] → v
Theorem 4
∗
If a → v , where v is a value, then a ⇒ v .
Proof.
Follows from the two properties below and an easy induction on the length
∗
of the reduction sequence a → v .
1 v ⇒ v for all values v (trivial)
2 If a → b and b ⇒ v , then a ⇒ v (case analysis).
e(x) = v
e`x ⇒v
Lexical scoping
let x = 1 in
let f = λy.x in
let x = "foo" in
f 0
Function closures
(P.J. Landin, 1964)
(λx.a)[e]
of the function text and an environment e associating values to the free
variables of the function.
let x = 1 in x 7→ 1
let f = λy.x in x 7→ 1; f 7→ (λy.x)[x 7→ 1]
let x = "foo" in x 7→ "foo"; f 7→ (λy.x)[x 7→ 1]
f 0 evaluate x in environment x 7→ 1; y 7→ 0
e(x) = v
e`N⇒N e ` λx.a ⇒ (λx.a)[e]
e`x ⇒v
e ` a ⇒ (λx.c)[e 0 ] e ` b ⇒ v0 e 0 + (x 7→ v 0 ) ` c ⇒ v
e`ab⇒v
λx. (λy. y x) x
| | |
λ. (λ. 1 2) 1
e = v1 . . . vn . . . vm
e`N⇒N e ` λ.a ⇒ (λ.a)[e]
e ` n ⇒ vn
e ` a ⇒ (λ.c)[e 0 ] e ` b ⇒ v0 v 0 .e 0 ` c ⇒ v
e`ab⇒v
type term = Const of int | Var of int | Lam of term | App of term * term
e = v1 . . . vn ≈ [1 ← v1 ; . . . ; n ← vn ]
Explicit substitutions, M. Abadi, L. Cardelli, P.L. Curien, J.J. Lévy, Journal of Functional
Programming 6(2), 1996.
Confluence properties of weak and strong calculi of explicit substitutions, P.L. Curien, T.
Hardin, J.J. Lévy, Journal of the ACM 43(2), 1996.
n[id] → n
1[a.e] → a
(n + 1)[a.e] → n[e]
β reduction:
(λ.a)[e] b → a[b.e]
((λ.a)[e] b)[e 0 ]
. &
a[b.e][e 0 ] ((λa)[e][e 0 ]) b[e 0 ]
Additional rules: