Lambda-calculus
Lambda culculus:
First invented in mid 1960s by Peter Latin. computations are described as mathematical objects where rigorous statements can be proved.
Syntax
t : : = terms: x variable λ x . t abstraction t t application \begin{array}{rlr} \mathrm{t}::= & \text { terms: } \\ & \mathrm{x} & \text { variable } \\ & \lambda \mathrm{x} . \mathrm{t} & \text { abstraction } \\ & \mathrm{t\ t} & \text { application } \end{array} t::= terms: xλx.tt t variable abstraction application
AST
abstract syntax: a tree that applies the grammar (AST: abstract syntax tree), instead of the superficial string.
Translation: by a compilers, first a lexical analyzer split the string into tokens and then a parser constructs the tree.
优先级:application优先给左侧的内容加括号,lamdba优先向右延伸
eg: s 1 s 2 … s n → ( … ( ( s 1 s 2 ) s 3 ) … s n ) s_1 s_2\dots s_n \to (\dots((s_1s_2)s_3)\dots s_n) s1s2…sn→(…((s1s2)s3)…sn) λ t 1 . … λ t n . s 1 … s n → λ t 1 . ( λ t 2 . ( … ( λ t n . s 1 ) … ) s n ) \lambda t_1.\dots\lambda t_n . s_1\dots s_n\to\lambda t_1.(\lambda t_2.(\dots (\lambda t_n.s_1 )\dots)s_{n}) λt1.…λtn.s1…sn→λt1.(λt2.(…(λtn.s1)…)sn) λ x . λ y . x y x → λ x ⋅ ( λ y ⋅ ( ( x y ) x ) ) : \lambda x . \lambda y . x\ y\ x \to\lambda x \cdot(\lambda y \cdot((x y) x)): λx.λy.x y x→λx⋅(λy⋅((xy)x)):
Scope
An occurrence of x x x is bound if it’s in λ x \lambda x λx.
λ x . x \lambda x.x λx.x: identical
Semantics
( λ x . t 12 ) t 2 ⟶ [ x ↦ t 2 ] t 12 \left(\lambda \mathrm{x} . \mathrm{t}_{12}\right) \mathrm{t}_2 \longrightarrow\left[\mathrm{x} \mapsto \mathrm{t}_2\right] \mathrm{t}_{12} (λx.t12)t2⟶[x↦t2]t12
here [ x ↦ t 2 ] t 12 \left[\mathrm{x} \mapsto \mathrm{t}_2\right] \mathrm{t}_{12} [x↦t2]t12 means the term obtained by replacing all free occurrences of x x x in t 12 t_{12} t12 by t 2 t_2 t2.
eg: ( λ x . x ) y → y (\lambda x. x)y\to y (λx.x)y→y. namely apply func i d id id to y y y.
By church, a term in ( λ x . t 12 ) t 2 (\lambda x. t_{12}) t_2 (λx.t12)t2 is a redex (reducible expression). There are many types of redex in implementation, e.g., full redex, normal order, call by name, etc.
Encoding of T/F
t
r
u
=
λ
t
.
λ
f
.
t
;
f
l
s
=
λ
t
.
λ
f
.
f
;
\begin{aligned} & \mathrm{tru}=\lambda \mathrm{t} . \lambda \mathrm{f} . \mathrm{t} ; \\ & \mathrm{fls}=\lambda \mathrm{t} . \lambda \mathrm{f} . \mathrm{f} ; \end{aligned}
tru=λt.λf.t;fls=λt.λf.f;eg:
⟶
t
r
u
v
w
=
(
λ
t
.
λ
f
.
t
)
v
‾
w
⟶
(
λ
f
.
v
w
)
‾
→
v
\begin{aligned} & \longrightarrow tru\ v\ w \\ & =\underline{(\lambda t . \lambda f . t) v\ } w \\ & \longrightarrow \underline{(\lambda f . v\ w)}\to v \end{aligned}
⟶ tru v w =(λt.λf.t)v w⟶(λf.v w)→v注意:
步骤 1:函数应用
- 首先我们用
t
r
u
t r u
tru 应用
v
v
v 和
w
w
w :
tru v w = ( λ t . λ f . t ) v w \operatorname{tru} v w=(\lambda t . \lambda f . t) v w truvw=(λt.λf.t)vw
步骤 2:替换参数 - 在这个步骤中, 我们将
v
v
v 替换到
t
t
t 的位置上:
= ( λ f . t ) → ( λ f . v ) w =(\lambda f . t) \rightarrow(\lambda f . v) w =(λf.t)→(λf.v)w
这表示我们得到了一个新的函数 λ f . v \lambda f . v λf.v ,它接受一个参数 f f f (虽然在这个例子中并没有实际使用)。
步骤 3:应用新函数 - 接下来, 我们将这个新函数 λ f . v \lambda f . v λf.v 应用到参数 w w w :
=
(
λ
f
.
v
)
w
=(\lambda f . v) w
=(λf.v)w
步骤 4:替换参数
- 这个步骤会将
w
w
w 替换到
f
f
f 的位置,但因为
v
v
v 并不依赖于
f
f
f, 所以返回的结果是
v
v
v :
= v =v =v
Church Numerals
c 0 = λ s ⋅ λ z ⋅ z c 1 = λ s ⋅ λ z ⋅ s ; c 2 = λ s ⋅ λ z ⋅ s ( s ) ; c 3 = λ s ⋅ λ z ⋅ s ( s ( s ) ) ; etc. \begin{aligned} & \mathrm{c}_0=\lambda \mathrm{s} \cdot \lambda \mathrm{z} \cdot \mathrm{z} \\ & \mathrm{c}_1=\lambda \mathrm{s} \cdot \lambda \mathrm{z} \cdot \mathrm{s} ; \\ & \mathrm{c}_2=\lambda \mathrm{s} \cdot \lambda \mathrm{z} \cdot \mathrm{s}(\mathrm{s}) ; \\ & \mathrm{c}_3=\lambda \mathrm{s} \cdot \lambda \mathrm{z} \cdot \mathrm{s}(\mathrm{s}(\mathrm{s})) ; \\ & \text { etc. } \end{aligned} c0=λs⋅λz⋅zc1=λs⋅λz⋅s;c2=λs⋅λz⋅s(s);c3=λs⋅λz⋅s(s(s)); etc. plus = λ m ⋅ λ n ⋅ λ s ⋅ λ z ⋅ m s (n s z); \text { plus }=\lambda m \cdot \lambda n \cdot \lambda s \cdot \lambda z \cdot m \text { s (n s z); } plus =λm⋅λn⋅λs⋅λz⋅m s (n s z);
Recursion
lambda calculus中有一些奇怪的现象:
term with no normal form (normal form: term that cannot take a step under evaluation): diverge
-
divergent combinator: omega = ( λ x . x x ) ( λ x . x x ) \text { omega }=(\lambda x. x\ x)(\lambda x. x\ x) omega =(λx.x x)(λx.x x). Use redex will only get o m e g a omega omega itself.
-
fixed-point combinator: f i x = λ f ⋅ ( λ x ⋅ f ( λ y ⋅ x x y ) ) ( λ x ⋅ f ( λ y ⋅ x x y ) ) f i x=\lambda f \cdot(\lambda x \cdot f(\lambda y \cdot x x y))(\lambda x \cdot f(\lambda y \cdot x x y)) fix=λf⋅(λx⋅f(λy⋅xxy))(λx⋅f(λy⋅xxy))
使用:(以factor为例)
g = λ \mathrm{g}=\lambda g=λ fct. λ n \lambda \mathrm{n} λn. if realeq n c 0 \mathrm{n} \mathrm{c}_0 nc0 then c 1 \mathrm{c}_1 c1 else (times n ( \mathrm{n}( n( fct ( ( ( prd n ) ) \mathrm{n})) n)) ) factorial factorial = fix g.
formal def of substitution
[ x ↦ s ] x = s [ x ↦ s ] y = y if y ≠ x [ x ↦ s ] ( λ y ⋅ t 1 ) = λ y ⋅ [ x ↦ s ] t 1 if y ≠ x and y ∉ F V ( s ) [ x ↦ s ] ( t 1 t 2 ) = [ x ↦ s ] t 1 [ x ↦ s ] t 2 \begin{array}{lll} {[x \mapsto s] x} & =s & \\ {[x \mapsto s] y} & =y & \text { if } y \neq x \\ {[x \mapsto s]\left(\lambda y \cdot t_1\right)} & =\lambda y \cdot[x \mapsto s] t_1 & \text { if } y \neq x \text { and } y \notin F V(s) \\ {[x \mapsto s]\left(t_1 t_2\right)} & =[x \mapsto s] t_1[x \mapsto s] t_2 & \end{array} [x↦s]x[x↦s]y[x↦s](λy⋅t1)[x↦s](t1t2)=s=y=λy⋅[x↦s]t1=[x↦s]t1[x↦s]t2 if y=x if y=x and y∈/FV(s)
this def is based on some natural intutions.
Further Readings
The untyped lambda-calculus was developed by Church and his co-workers in the 1920s and ’30s (Church, 1941). The standard text for all aspects of the untyped lambda-calculus is Barendregt (1984); Hindley and Seldin (1986) is less comprehensive, but more accessible. Barendregt’s article (1990) in the Handbook of Theoretical Computer Science is a compact survey. Mate rial on lambda-calculus can also be found in many textbooks on functional programming languages (e.g. Abelson and Sussman, 1985; Friedman, Wand, and Haynes, 2001; Peyton Jones and Lester, 1992) and programming language semantics (e.g. Schmidt, 1986; Gunter, 1992; Winskel, 1993; Mitchell, 1996). A systematic method for encoding a wide variety of data structures as lambdaterms can be found in Böhm and Berarducci (1985).
Despite its name, Curry denied inventing the idea of currying. It is commonly credited to Schönfinkel (1924), but the underlying idea was familiar to a number of 19th-century mathematicians, including Frege and Cantor.