\documentclass{book}
\renewcommand{\chaptername}{Lecture}
\usepackage{amsmath}
\usepackage{ctable}
\usepackage[mathletters]{ucs}
\usepackage[utf8x]{inputenc}
% Redefine labelwidth for lists; otherwise, the enumerate package will cause
% markers to extend beyond the left margin.
\makeatletter\AtBeginDocument{%
  \renewcommand{\@listi}
    {\setlength{\labelwidth}{4em}}
}\makeatother
\usepackage{enumerate}
\usepackage[breaklinks=true,unicode=true]{hyperref}
\setlength{\parindent}{0pt}
\setlength{\parskip}{6pt plus 2pt minus 1pt}
%\setcounter{secnumdepth}{0}


\begin{document}

\setcounter{chapter}{8}

\chapter{Lambda Calculus}

We now look at lambda calculus, the theoretical stuff that underlies
functional programming. It was introduced by Alonzo Church to formalise
two key concepts when dealing with functions in mathematics and logic
namely: function definition and function application. In this lecture,
we build enough stuff to get a lambda calculus evaluator.

\begin{verbatim}

> module Lambda where
> import Data.List -- I need some standard list functions
\end{verbatim}
We start with an example. Consider the squaring function, i.e.~the
function that maps $x$ to $x^2$. In the notation of lambda calculus this
is denoted as $\lambda x . x^2$. This is called a lambda abstraction.
Apply a function $f$ on an expression $N$ is written as $f N$. The key
rule in expression evaluation is the $\beta$-reduction: the expression
$(\lambda x. M) N$ reduces under $\beta$-reduction to the expression $M$
with $N$ substituted in it. We now look at lambda calculus formally.

The goal of this lecture is to introduce basics of lambda calculus and
on the way implement a small lambda calculus interpreter.

\section{Abstract syntax}

As with any other formal system we first define its abstract syntax. A
lambda calculus expression is defined via the grammar

\[ e := v | e_1 e_2 | \lambda x . e \]

Here $e_1$ and $e_2$ expressions themselves. We now capture this
abstract syntax as a Haskell data type

\begin{verbatim}

> -- | The datatype that captures the lambda calculus expressions.
> data Expr = V    String       -- ^ A variable
>           | A    Expr   Expr  -- ^ functional application
>           | L    String Expr  -- ^ lambda abstraction
>           deriving Show
\end{verbatim}
\section{Free and bound variables}

The notion of free and bound variables are fundamental to whole of
mathematics. For example in the integral $\int \sin{xy} dy$, the
variable $x$ occurs \emph{free} where as the variables $y$ occurs
\emph{bound} (to the corresponding $\int dy$). Clearly the value of the
expression does \emph{not} depend on the bound variable; in fact we can
write the same integral as $\int \sin{xt} dt$.

In lambda calculus we say a variable occurs bound if it can be linked to
a lambda abstraction. For example in the expression $\lambda x. xy$ the
variable $x$ is bound where as $y$ occurs free. A variable can occur
free as well as bound in an expression --- consider $x$ in
$\lambda y. x (\lambda x.x)$.

Formally we can define the free variables of a lambda expression as
follows.

\[FV (v)            = \{ v\}\]
\[FV(e_1 e_2)       = FV(e_1) \cup FV(e_2)\]
\[FV (\lambda x. e) = FV(e) \setminus \{ x \}\]

We turn this into haskell code

\begin{verbatim}

> freeVar :: Expr -> [String]
> freeVar (V x  ) = [x]
> freeVar (A f e) = freeVar f `union` freeVar e
> freeVar (L x e) = delete x $ freeVar e
\end{verbatim}
\section{Variable substitution}

We often need to substitute variables with other expressions. Since it
is so frequent we give a notation for this. By $M [ x := e]$, we mean
the expression obtained by replacing all free occurrence of $x$ in $M$
by $e$. Let us code this up in haskell.

\begin{verbatim}

> subst :: Expr -> String -> Expr -> Expr
> subst var@(V y)   x e | y == x    = e
>                       | otherwise = var
> subst (A f a) x e                 = A (subst f x e) (subst a x e)
> subst lam@(L y a) x e | y == x    = lam
>                       | otherwise = L y (subst a x e)
\end{verbatim}
\section{Change of bound variables ($\alpha$-reduction)}

You are already familiar with this in mathematics. If we have an
integral of the kind $\int x t dt$ we can rewrite it as $\int x y dy$ by
a change of variable. The same is true for lambda calculus. We say call
the ``reduction'' $\lambda x .M \leftarrow \lambda t. M [x :=t]$ as the
$\alpha$-reduction. However care should be taken when the new variable
is chosen. Two pitfalls to avoid when performing $\alpha$-reduction of
the expression $\lambda x. M$ to $\lambda t. M[x := t]$ is

\begin{enumerate}[1.]
\item
  The variable $t$ should not be free in $M$ for otherwise by changing
  from $x$ to $t$ we have bound an otherwise free variable. For example
  if $M=t$ then $\lambda t. M[x=t]$ becomes $\lambda t.t$ which is
  clearly wrong.
\item
  If $M$ has a free occurrence of $x$ in the scope of a bound occurrence
  of $t$ then we cannot perform change the bound variable $x$ to $t$.
  For example consider $M = \lambda t. x t$. Then $\lambda t. M[x=t]$
  will become $\lambda t. \lambda t. t t$ which is clearly wrong.
\end{enumerate}
Clearly, one safe way to do $\alpha$-reduction on $\lambda x. M$ is to
use a fresh variable $t$, i.e.~a variable that is neither free nor bound
in $M$. We write a helper function to compute all the variables of a
lambda calculus expression.

\begin{verbatim}

> varsOf :: Expr -> [String]
> varsOf (V x)   = [x]
> varsOf (A f e) = varsOf f `union` varsOf e
> varsOf (L x e) = varsOf e `union` [x]
\end{verbatim}
We now give the code to perform a safe change of bound variables.

\begin{verbatim}

> alpha :: Expr -> [String] -> Expr
> alpha (A f e) vars                     = A (alpha f vars) (alpha e vars)
> alpha (L x e) vars | x `elem` vars     = L t $ alpha e' vars
>                    | otherwise         = L x $ alpha e  vars
>       where t  = fresh (varsOf e `union` vars)
>             e' = subst e x (V t)
> alpha  e       _                       = e
\end{verbatim}
\section{Function evaluation ($\beta$-reduction)}

The way lambda calculus captures computation is through $\beta$
reduction. We already saw what is $\beta$ reduction. Under beta
reduction, an expression $(\lambda x . M) N$ reduces to $M [x := N]$,
where $M[x:=N]$ denotes substitution of \emph{free} occurrences of $x$
by $N$. However, there is a chance that a free variable of $N$ could
become bound suddenly. For example consider $N$ to be just $y$ and $M$
to be $\lambda y. x y$. Then reducing $(\lambda x . M) N$ to $M[x := N]$
will bind the free variable $y$ in $N$.

We now give the code for $\beta$ reduction. It performs one step of beta
reduction that too if and only if the expression is of the form
$(\lambda x . M) N$.

\begin{verbatim}

> beta :: Expr -> Expr
> beta (A (L x m) n) = carefulSubst m x n
> carefulSubst m x n = subst (alpha m $ freeVar n) x n
> 
\end{verbatim}
\section{Generating Fresh variables}

We saw that for our evaluator we needed a source of fresh variables. Our
function fresh is given a set of variables and its task is to compute a
variable name that does not belong to the list. We use diagonalisation,
a trick first used by Cantor to prove that Real numbers are of strictly
higher cardinality than integers.

\begin{verbatim}

> fresh :: [String] -> String
> fresh = foldl diagonalise "a"
>
> diagonalise  []        []               = "a" -- diagonalised any way
> diagonalise  []      (y:ys) | y == 'a'  = "b" -- diagonalise on this character
>                             | otherwise = "a" 
> diagonalise  s        []                =  s  -- anyway s is differnt from t
> diagonalise s@(x:xs) (y:ys) | x /= y    = s   -- differs at this position anyway
>                             | otherwise = x : diagonalise xs ys
>
\end{verbatim}
\section{Exercise}

\begin{enumerate}[1.]
\item
  Read up about
  \href{http://en.wikipedia.org/wiki/Beta\_normal\_form}{$\beta$-normal}
  forms. Write a function that converts a lambda calculus expression to
  its normal form if it exists. There are different evaluation
  strategies to get to $\beta$-normal form. Code them all up.
\item
  The use of \texttt{varOf} in $\alpha$-reduction is an overkill. See if
  it can be improved.
\item
  Read about $\eta$-reduction and write code for it.
\end{enumerate}

\end{document}
