Chapter 1: Introduction
Overview
The lambda calculus can be thought of as the theoretical foundation of functional programming. It is a Turing complete language.
The lambda calculus expressions () consist of following three types of elements:
Don't worry about obscure mathematical definition above, let's learn it by examples.
Lambda Function
Let's take an anonymous function for example:
Substitute for :
Similar function donated in lambda calculus requires explicit indication of parameter as:
Substitution is renamed to application with another syntax similar to multiplication in regular mathematics:
A name could also be assigned to the function like this:
In lambda calculus, it should be rewritten as:
At the first glance, you may be confused. Don't worry, let's check it in detail.
Compare following two expressions:
We may say, is a variable, whose value equals .
Similarly, let's say, is also a variable, whose value equals a function.
It reveals one of core ideas about lambda calculus. That is, functions are also variables. You will get accustomed to this soon.
There are some conventions of named functions. For example:
Identity function returns its parameter unchanged. It will be mentioned again later.
Function as Return Value
Since now functions are also variables, please view following example:
is a function whose return value is also a function. Just like normal value functions, whose return value is determined by its parameters, the function returned by is also determined by its parameter . is "plus 3 function" and is "plus 4 function". Then we may apply it again with another parameter to obtain further result.
Free variables are those whose value is not determined by its direct enclosing function. Free variable of inner function taking the value from outer function is called capture.
Currying and Uncurrying
If we treat consecutive lambda function chain as one multiple-parameter function:
We may review the previous example from another perspective:
Pay attention to the line . It partially applies the function with only first parameter and yields a function taking successive ones, which is called partial application. In fact, the definition of partial application of uncurrying multiple-parameter function is exactly corresponding to the practice of application of currying consecutive lambda function chain - as if it is.
From the one perspective of associativity, application is also similar to multiplication in regular mathemtics just as syntax do - contiguous operands should be applied from left to right. That is,
represents apply with , and apply previous result with .
From the other persepctive of currying and uncurrying, left side of equation reprensents apply with together and right side of equation represents apply it step by step. But at the end of day, they are equivalent and no more than two different ways to understand the same application process.
Function as Parameter
Similarly, functions could be passed as parameters, too:
It is remarkable that produces a new function from an old one. Isn't it cool to manipulate functions instead of just values?
Reduction
To simplify lambda calculus expressions, three kinds of reductions will be introduced.
Alpha reduction
reduction is also known as equivalence. Substitution of parameter name does not change semantics. It is similar to following cases in regular mathematics:
Note despite semantics unchanged, name conflicts and shadowing may casue ambiguity and confusion:
It is more damaging than those cases in regular mathematics:
Beware outer and inner are differnet ones.
Beta reduction
This is exactly what application is all about. Most common reduction during lambda calculus is the reduction.
Note that a constant function cannot be reduced to the constant even if the constant is independent from the parameter. An application is necessary.
Eta reduction
reduction is not that obvious. To prove this equation, we'd better introduce a helper variable to be applied with:
Applying them with identical parameter yield identical result. That's why they are considered equivalent.