Lab 7: Lambda calculus
This lab focuses on lambda calculus. First, we focus on the syntax of lambda-calculus.rkt
To follow the exercises, it is recommended to have a piece of paper, a pen, DrRacket IDE installed, and the interpreter. To use the interpreter, download the above-mentioned file and store it in a directory where you want to create your own code. Then create a new Racket file starting as follows:
#lang racket
(require "lambda-calculus.rkt")'(λ x : (λ y : ((x y) (λ a : (λ b : b)))))So we had to add the outermost parenthesis, expand the shortcuts Ctrl+\. Instead of the dot symbol, the colon symbol is used.
The module lambda-calculus.rkt provides the following functions:
| Function | Description |
|---|---|
(draw-expr expr) | draws the syntax tree the given expr; redexes are colored in red |
(substitute expr var val) | substitutes val for the free occurrences of var in expr |
(reduce expr) | reduces expr by a one-step |
(eval expr [info 'quiet]) | finds the normal form of expr; if info is set to 'verbose, displays all the steps; if info is 'tree, then all the steps are drawn as trees |
Exercise 1
Draw the syntax tree of the
We will use the helper function draw-expr. First, create the correct representation as an S-expression:
'((λ x : (y (x x))) (λ y : (y (x x))))Then evaluate the following function call:
(draw-expr '((λ x : (y (x x))) (λ y : (y (x x)))))
Displays the tree below: 
An occurrence of a variable
Exercise 2
Draw the syntax tree of the
Try first to draw the tree on paper. Then compare your result with the result returned by the function draw-expr. The
'(λ y : ((x y) (λ a : (λ b : b))))Exercise 3
Find all redexes in
Hint
Try to find the redexes. Then call (draw-expr expr) for expr being the following S-expression:
'(((λ x : (x y)) z) ((λ u : u) ((λ v : v) z)))The roots of redexes are colored red. To check that your reduction was correct, call
(reduce '(((λ x : (x y)) z) ((λ u : u) ((λ v : v) z))))Exercise 4
Recall that multiplication of two numbers is computed by
Find the normal form of
Hint
Once you do it on paper, check your result in Racket. You can use Racket definitions and semiquoting to make your
(define zero '(λ s : (λ z : z)))
(define one '(λ s : (λ z : (s z))))
(define M '(λ a : (λ b : (λ c : (a (b c))))))
(eval `((,M ,zero) ,one) 'verbose) ; displays each reduction step as λ-expression
(eval `((,M ,zero) ,one) 'tree) ; draws each reduction step as syntax treeExercise 5
Recall that a pair
The projections into the first and second components can be obtained by applying
We can even define a cons function by
(define T '(λ x : (λ y : x)))
(define F '(λ x : (λ y : y)))
(define CONS
'(λ a : (λ b : (λ z : ((z a) b)))))
(eval `(((,CONS a) b) ,T))
(eval `(((,CONS a) b) ,F))Write a
Hint
The desired
Solution
Once you have it, define SWAP and check that it correctly swaps the components:
(eval `(,SWAP ((,CONS a) b))) => '(λ z : ((z b) a))Solution
(define SWAP `(λ p : (λ z : ((z (p ,F)) (p ,T)))))Exercise 6
Since we can create pairs, we can create lists as in Racket. We represent the empty list by the false value '(a b) by
(define lst `((,CONS a) ((,CONS b) ,F)))
(eval `(,lst ,T)) => 'a
(eval `((,lst ,F) ,T)) => 'bWrite a
Hint
A list is either a pair or
where
Solution
Check your solution in Racket.
Code
(define neg `(λ x : ((x ,F) ,T)))
(define NULL? `(λ p : ((p (λ a : (λ b : ,neg))) ,T)))
(eval `(,NULL? ,F)) ; => T
(eval `(,NULL? ,lst)) ; => FExercise 7
Define a
Hint
Follow the approach from the lecture where we defined a function
which we turned into a recursive one by
Recall:
You also need the successor function
for adding
(define len
(lambda (p) (if (null? p)
0
(+ (len (cdr p)) 1))))Modify the NULL? from the previous exercise. Adding
Solution
Check your solution in Racket:
Code
(define S '(λ w : (λ y : (λ x : (y ((w y) x))))))
(define Y '(λ y : ((λ x : (y (x x))) (λ x : (y (x x))))))
(define LEN
`(λ r :
(λ lst : (
((,NULL? lst) ,zero)
(,S (r (lst ,F)))))))
(eval `((,Y ,LEN) ,F)) ; => 0
(eval `((,Y ,LEN) ((,CONS a) ,F))) ; => 1
(eval `((,Y ,LEN) ((,CONS a) ((,CONS b) ,F)))) ; => 2