Scarlet Serenade

Computation | Lambda Calculus

  • bound var: a var that's associated with some λ
  • free var: a var not associated with any `λ

直观上来说,如果 x is bound 则 x 在一个左边为 xλ 的子树

A closed term is one in which all identifiers are bound.


In the pure lambda calculus, any abstraction is a value. Remember, an abstraction λx. e is a function; in the pure lambda calculus, the only values are functions.

In an applied lambda calculus with integers and arithmetic operations, values also include integers. Intuitively, a value is an expression that can not be reduced/executed/simplified any further.


substitution

α-equivalence: we can change the name of bound variables without changing the meaning of functions.
Thus λx. x is the same function as y. y

Expressions e1 and e2 that differ only in the name of bound variables are called α-equivalent ("alpha equivalent"), sometimes written e1 =α e2.


β-equivalence: We write e1{e2/x} to mean expression e1 with all free occurrences of x replaced with e2.

((λx.λy.x)y)z
        ->  ((λy.x)[y/x])z   // substitute y for x in the body of "λy.x"
        ->  ((λy'.x)[y/x])z  // after alpha reduction
        ->  (λy'.y)z         // first beta-reduction complete!
        ->  y[z/y']          // substitute z for y' in "y"
        ->  y                // second beta-reduction complete!

we call ((λx.λy.x)y)z and y are beta-equivalent

Note that the term "beta-reduction" is perhaps misleading, since doing beta-reduction does not always produce a smaller lambda expression. In fact, a beta-reduction can:

  • not change: (λx.xx)(λx.xx) → (λx.xx)(λx.xx)
  • increase: (λx.xxx)(λx.xxx) → (λx.xxx)(λx.xxx)(λx.xxx) → (λx.xxx)(λx.xxx)(λx.xxx)(λx.xxx)
  • decrease: (λx.xx)(λa.λb.bbb) → (λa.λb.bbb)(λa.λb.bbb) → λb.bbb

normal form

We say that a lambda expression without redexes (applications of a function to an argument) is in normal form, and that a lambda expression has a normal form iff there is some sequence of beta-reductions and/or expansions that leads to a normal form.

(λx.λy.y)((λz.zz)(λz.zz)). This lambda expression contains two redexes:

  • the whole expression
  • the argument itself: ((λz.zz)(λz.zz))

如果我们先对 argument 做 beta reduction 则永远不会得到 norm form 但是如果先对第一个 redex 做则可以

leftmost-outermost or normal-order-reduction (NOR) 能够保证得到 norm form (如果存在的话) Definition: An outermost redex is a redex that is not contained inside another one. (Similarly, an innermost redex is one that has no redexes inside it.) In terms of the abstract-syntax tree, an "apply" node represents an outermost redex iff

  • it represents a redex (its left child is a lambda), and

-- it has no ancestor "apply" node in the tree that also represents a redex.

                            apply  <-- not a redex
                           /     \
an outermost redex --> apply      apply <-- another outermost redex
                      /    \      /    \
                     λ     ...   λ      apply  <-- redex, but not outermost
                    / \         / \     /   \     
                  ... ...      ... ... λ    ...

If it is a function that ignores its argument, then reducing that redex can make other redexes (those that define the argument) "go away"; however, reducing an argument will never make the function "go away".

Evaluation strategy

  • call by value: leftmost-innermost (applicative-order reduction (AOR))
  • call by name: leftmost-outermost (normal-order-reduction (NOR))
  • call by need: like call by name but the result of the evaluation is saved and is then reused for each subsequent use of the formal.