COMS W4115
  Programming Languages and Translators
  Lecture 23: April 22, 2013
  The Lambda Calculus
 
Outline
 
  - Reduction orders
- The Church-Rosser theorems
- The Y combinator
- Implementing factorial using the Y combinator
- Church numerals
- Arithmetic
- Logic
- Other programming language constructs
- The influence of the lambda calculus on functional languages
1. Reduction Orders
 
  - Programming languages use many different techniques to pass parameters to procedures
      such as call by value, call by reference, call by value-return, call by name, and so on.
      We can model many of these parameter-passing mechanisms using the lambda calculus.
- The order in which reductions are applied within a lambda expression
      can affect the final result.
      We will use the terms reduction order and evaluation order synonymously.
- A reducible expression (redex) in a lambda expression is a subexpression
      that can be reduced using beta reduction.
- An expression that contains no redexes is said to be in normal form.
- Some reduction orders for an expression may yield a normal form
      expression while
      other orders may not. For example, consider the expression
  
  
- This expression has two redexes:
   - The entire expression is a redex in which we can apply the function
       (λx.1)to
       the argument((λx.x x)(λx.x x))to yield the value 1.
- The rightmost subexpression ((λx.x x)(λx.x x))is also a redex in which
       we can apply the function(λx.x x)to the argument(λx.x x). But if we do this reduction we get same subexpression:(λx.x x)(λx.x x)→(λx.x x)(λx.x x).
       Thus, continuing this order of evaluation will not terminate in a normal form.
- A remarkable property of lambda calculus is that every lambda expression
      has a unique normal form if one exists.
- The expression (λx.1)((λx.x x)(λx.x x))has the normal form 1.
- The expression (λx.x x)(λx.x x)does not have a normal form
      because it always evaluates to itself. We can think of this expression as
      a representation for an infinite loop.
- There are two common reduction orders for lambda expressions:
      normal order evaluation and applicative order evaluation.
- Normal order evaluation
   - In normal order evaluation we always reduce the leftmost outermost redex at each step.
- The first reduction order above is a normal order evaluation.
- If an expression has a normal form, then normal order evaluation will always find it.
- Applicative order evaluation
   - In applicative order evaluation we always reduce the leftmost innermost redex
       at each step.
- The second reduction order above is an applicative order evaluation.
- Thus, even though an expression may have a normal form, applicative order evaluation
       may fail to find it.
2. The Church-Rosser Theorems
 
  - A remarkable property of lambda calculus is that every expression has a unique
      normal form if one exists.
- Church-Rosser Theorem I: If e →* fande →* gby any two reduction orders,
      then there always exists
      a lambda expressionhsuch thatf →* handg →* h.
   - A corollary of this theorem is that no lambda expression can be reduced to
       two distinct normal forms. To see this, suppose fandgare in normal form. The Church-Rosser theorem says there must be an expressionhsuch thatfandgare each reducible
       toh.  Sincefandgare in normal form,
       they cannot have any redexes sof = g = h.
- This corollary says that all reduction sequences that terminate will always
       yield the same result and that result must be a normal form.
- The term confluent is often applied to a rewriting system that has the
       Church-Rosser property.
- Church-Rosser Theorem II: If e →* fandfis in normal form, then there exists a normal order
      reduction sequence frometof.
3. The Y Combinator
 
  - The Ycombinator (sometimes called the paradoxical combinator)
      is a function that takes a functionGas an argument and returnsG(YG).
      With repeated applications we can getG(G(YG)), G(G(G(YG))),... .
- We can implement recursive functions using the Ycombinator.
- Yis defined as follows:
   - (λf.(λx.f(x x))(λx.f(x x)))- 
  
- Let us evaluate YGwhereGis any expression:
    - (λf.(λx.f(x x))(λx'.f(x' x'))) G
 → (λx.G(x x))(λx'.G(x' x'))
 → G((λx'.G(x' x'))(λx'.G(x' x')))
 ↔ G((λf.(λx.f(x x))(λx.f(x x)))G)
 = G(YG)
 
- Thus, YG →* G(YG);
      that is,YGreduces to a call ofGon(YG).
- We will use Yto implement recursive functions.
- Yis an example of a fixed-point combinator.
4. Implementing Factorial using the Y Combinator
 
  - If we could name lambda abstractions, we could define the
      factorial function with the following recursive definition:
    - FAC = (λn.IF (= n 0) 1 (* n (FAC (- n 1 ))))
- where IFis a conditional function.
- However, functions in lambda calculus cannot be named; they
      are anonymous.
- But we can express recursion as the fixed-point of a function G.
      To do this, let us simplify the essence of the problem.
      We begin with a skeletal recursive definition:
- By performing beta abstraction on FAC, we can transform its
      definition to:
    - FAC = (λf.(λn.(... f ...))) FAC
 -     = G FAC
- where
   - G = λf.λn.IF (= n 0) 1 (* n (f (- n 1 )))
- Beta abstraction is just the reverse of beta reduction.
- The equation
- says that when the function Gis applied toFAC,
      the result isFAC.
      That is,FACis a fixed-point ofG.
- We can use the Y combinator to implement FAC:
- As an example, let compute FAC 1:
   - FAC 1 = Y G 1
 = G (Y G) 1
 = λf.λn.IF (= n 0) 1 (* n (f (- n 1 ))))(Y G) 1
 → λn.IF (= n 0) 1 (* n ((Y G) (- n 1 ))))1
 → IF (= n 0) 1 (* n ((Y G) (- 1 1 )))
 → * 1 (Y G 0)
 = * 1 (G(Y G) 0)
 = * 1((λf.λn.IF (= n 0) 1 (* n (f (- n 1 ))))(Y G 0)
 → * 1((λn.IF (= n 0) 1 (* n ((Y G) (- n 1 ))))0
 → * 1(IF (= 0 0) 1 (* 0 ((Y G) (- 0 1 )))
 → * 1 1
 → 1
5. Church Numerals
 
  - Church numberals are a way of representing the integers in lambda calculus.
  
- Church numerals are defined as functions taking two parameters:
   - 0is defined as- λf.λx. x
- 1is defined as- λf.λx. f x
- 2is defined as- λf.λx. f (f x).
- 3is defined as- λf.λx. f (f (f x)).
- nis defined as- λf.λx. fn x
- nhas the property that for any lambda expressions- gand- y,- ngy →* gny.
      That is to say,- ngycauses- gto be
      applied to- yn times.
6. Arithmetic
  
   - In lambda calculus, arithmetic functions can be represented by
       corresponding operations on Church numerals.
- We can define a successor function succof three arguments that adds one
       to its first argument:
    - λn.λf.λx. f (n f x)
- Example: Let us evaluate succ 0:
- (λn.λf.λx. f (n f x)) 0
 → λf.λx. f (0 f x)
 = λf.λx. f ((λf.λx. x) f x)
 → λf.λx. f (λx. x) x)
 → λf.λx. f x
 = 1
- We can define a function addusing the identityf(m+n) =
             fm º fnas follows:
    - Example: Let us evaluate add 1 2:
- λm.λn.λf.λx. m f (n f x) 1 2
 →  λn.λf.λx. 1 f (n f x) 2
 →* λf.λx. f (f (f x))
 =  3
7. Logic
 
  - The boolean value true can be represented by a function of two arguments that
      always selects its first argument: λx.λy.x
- The boolean value false can be represented by a function of two arguments that
      always selects its second argument: λx.λy.y
- An if-then-else statement can be represented
      by a function of three arguments λc.λi.λe. c i ethat uses its
      conditioncto select either the if-partior the else-parte.
    - Example: Let us evaluate if true then 1 else 2:
- (λc.λi.λe. c i e) true 1 2
 → (λi.λe. true i e) 1 2
 → (λe. true 1 e) 2
 → true 1 2
 = (λx.λy.x) 1 2
 → (λy.1) 2
 → 1
 
- The boolean operators and, or, and not can be implemented as follows:
      - 
          and = λp.λq. p q p
 or  = λp.λq. p p q
 not = λp.λa.λb. p b a
 
- Example: Let us evaluate not true:
- (λp.λa.λb. p b a) true
 → λa.λb. true b a
 = λa.λb. (λx.λy.x) b a
 → λa.λb. (λy.b) a
 → λa.λb. b
 = false
(under renaming)
 
8. Other Programming Language Constructs
 
  - We can readily implement other programming language constructs in lambda calculus.
      As an example, here are lambda calculus expressions for various list operations
      such as
      cons (constructing a list),
      head (selecting the first item from a list), and
      tail (selecting the remainder of a list after the first item):
      - 
          cons = λh.λt.λf. f h t
 head = λl.l (λh.λt. h)
 tail = λl.l (λh.λt. t)
 
9. The Influence of The Lambda Calculus on Functional Languages
 
  - Our next lecture will be by Maria Taku who will talk about the influence
      of the lambda calculus on functional languages and her experiences
      implementing the PLT compiler project using OCaml.
10. Practice Problems
 
  - Evaluate (λx.((λw.λz. + w z)1))
               ((λx. xx)(λx. xx)))
               ((λy. * y 1) (- 3 2))using normal order evaluation and applicative order evaluation.
- Give an example of a code optimization transformation that has the Church-Rosser property.
- Evaluate FAC 2.
- Evaluate succ two.
- Evaluate add two three.
- Let mulbe the function
- Evaluate mul two three.
- Write a lambda expression for the boolean predicate isZeroand evaluateisZero one.
11. References
 
  - Simon Peyton Jones, The Implementation of Functional Programming Languages,
      Prentice-Hall, 1987.
- 
      Stephen A. Edwards: The Lambda Calculus  
- http://www.inf.fu-berlin.de/lehre/WS01/ALPI/lambda.pdf
- http://www.soe.ucsc.edu/classes/cmps112/Spring03/readings/lambdacalculus/project3.html
aho@cs.columbia.edu