User:Thepigdog/Lambda Calculus



Lambda calculus is a programming language based solely on lambda abstraction and function application.

Normally, in defining a function, the formal parameters are written after the function name. The Lambda Abstraction is an alternative representation that associates the formal parameters of a function with the expression that implements the function. This allows a function to be defined as an expression.

Today, the lambda calculus has applications in many different areas in mathematics, philosophy, linguistics, and computer science. Lambda calculus has played an important role in the development of the theory of programming languages and in the development of functional programming languages.

The lambda calculus also has many applications in proof theory. A major example of this is the Curry–Howard correspondence, which gives a correspondence between different systems of typed lambda calculus and systems of formal logic.

History
Alonzo Church invented the Lambda Calculus in the 1930s, originally to provide a new and simpler basis for mathematics. However soon after inventing it major logic problems were identified with the definition of the Lambda Abstraction.

The Kleene–Rosser paradox is an implementation of Richard's paradox in combinatory logic. Combinatory Logic is closely related to Lambda Calculus. Haskell Curry found that the key step in this paradox could be used to implement the simpler Curry's Paradox. The existence of this paradox meant that the Combinatory Logic, and Lambda Calculus, could not be both consistent and complete as a deductive system.

Alonzo Church then used the lambda Calculus as a programming language to formalized the concept of effective computability. In 1936, Alonzo Church and Alan Turing published independent papers showing that a general solution to the Entscheidungsproblem is impossible, assuming that the intuitive notation of "effectively calculable" is captured by the functions computable by a Turing machine (or equivalently, by those expressible in the lambda calculus). This assumption is now known as the Church–Turing thesis.

Lambda calculus is a simple universal model of computation. Turing showed in 1937 that any program written for a Turing machines could be written in lambda calculus and vice versa.

Peter Landin's 1965 paper A Correspondence between ALGOL 60 and Church's Lambda-notation, sequential procedural programming languages can be understood in terms of the lambda calculus, which provides the basic mechanisms for procedural abstraction and procedure (subprogram) application.

Introduction
Lambda calculus (also written as λ-calculus) is a formal system in mathematical logic and computer science for expressing computation based on function abstraction and application using variable binding and substitution. The name derives from the Greek letter lambda (λ) used to denote binding a variable in a function.

Lambda calculus is used and viewed in many ways,

Explanation
A lambda term represents a function that may be reduced until it cannot be reduced any further. It is then said to be in normal form. Informally it is then a "value". For example,
 * (λn.λf.λx.f (n f x)) λf.λx.f (f (f x)))

In this term, the abstraction λn represents a parameter. The term λf.λx.f (f (f x))) is bound to the parameter n giving it a value. Then every (in this case one) occurrence of n in λf.λx.f (n f x) is replaced by λf.λx.f (f (f x))), giving,
 * λf.λx.f (λf.λx.f (f (f x))) f x) 

This step is called beta reduction. The step is repeated on the sub term λf.λx.f (f (f x))) f x. Here
 * <tt>f</tt> is replaced by <tt>f</tt> in <tt>λx.f (f (f x)))</tt>

giving,
 * <tt>λf.λx.f (λx.f (f (f x))) x) </tt>

The beta reduction is repeated again on the sub term <tt>λx.f (f (f x))) x</tt>. Here
 * <tt>x</tt> is replaced by <tt>x</tt> in <tt>f (f (f x)))</tt>

giving,
 * <tt>λf.λx.f (f (f (f x))))</tt>

The expression can no longer be reduced and is regarded as being a value in normal formal.

In Church numerals, <tt>λf.λx.f (f (f (f x))))</tt> represents the number 5, because it applies the function <tt>f</tt> five times to the parameter <tt>x</tt>. This is an interpretation of the lambda term, but the term may also be regarded only as a function definition that cannot be further reduced.

As another example,
 * <tt>λx.((λf.λx.f (f x)) x)</tt>

This term cannot be reduced in the same way as the previous expression. But lambda calculus allows a second type of reduction called eta reduction. When a parameter <tt>λx</tt> is then used as a parameter to a sub term then they may both be eliminated, giving,
 * <tt>λf.λx.f (f x)</tt>

Each lambda abstractions defines a local variable, which is a placeholder which will be substituted with a value during beta reduction. The name is not regarded as important. Only the structure is important. So,
 * <tt>λf.λx.f (f x)</tt>

is regarded as being identical to,
 * <tt>λa.λb.a (a b)</tt>

Converting between the two forms is called alpha conversion.

There are some complications in the details of the naming of variables. As in other programming languages, the simple rule is that lambda terms behave as if each expression was parsed and every local variable renamed with a unique name.

The rules, described formally, define lambda calculus.
 * Beta reduction
 * Eta reduction
 * Alpha conversion

Lambda abstraction
In mathematics a function is defined in the form,


 * $$ f\ x = x^2 $$

Here I am using the functional notation $$ f\ x $$ instead of $$ f(x)$$ to represent the application of a function to a parameter. This is the notation for function application used in functional languages such as ML, Miranda and Haskell.

The lambda abstraction is conceived by considering what is the value of $$f$$. $$f$$ is a function, but what is it equal to? What is it's value? The lambda abstraction provides a notation for representing this value.


 * $$ f = \lambda x.x^2 $$

The lambda abstraction $$ \lambda x.x^2 $$ is also called an anonymous function, because it defines a function without giving it a name.

Problems with the Lambda Abstraction
The lambda abstraction is a definition. However defining something does not make it exist. Soon after discovering the lambda abstraction it was found to have inconsistencies when considered as a mathematical expression (see Kleene–Rosser paradox and Curry's Paradox).

The lambda abstraction was then used as the basis for a programming language, the Lambda Calculus. As a programming language the lambda calculus could not lean on mathematics as it's basis. Instead fundamental theorems about it's behavior had to be proved specifically for the lambda calculus.

Encoding datatypes
divide = <tt>λn.((λf.(λx.x x) (λx.f (x x))) (λc.λn.λm.λf.λx.(λd.(λn.n (λx.(λa.λb.b)) (λa.λb.a)) d ((λf.λx.x) f x) (f (c d m f x))) ((λm.λn.n(λn.λf.λx.n (λg.λh.h (g f)) (λu.x) (λu.u))m) n m))) ((λn.λf.λx.f (n f x)) n)</tt>

Computable functions and lambda calculus
A function F: N → N of natural numbers is a computable function if and only if there exists a lambda expression f such that for every pair of x, y in N, F(x)=y if and only if f <tt>x</tt> =β <tt>y</tt>, where <tt>x</tt> and <tt>y</tt> are the Church numerals corresponding to x and y, respectively and =β meaning equivalence with beta reduction. This is one of the many ways to define computability; see the Church-Turing thesis for a discussion of other approaches and their equivalence.

Undecidability of equivalence
There is no algorithm that takes as input two lambda expressions and outputs <tt>TRUE</tt> or <tt>FALSE</tt> depending on whether or not the two expressions are equivalent. This was historically the first problem for which undecidability could be proven. As is common for a proof of undecidability, the proof shows that no computable function can decide the equivalence. Church's thesis is then invoked to show that no algorithm can do so.

Church's proof first reduces the problem to determining whether a given lambda expression has a normal form. A normal form is an equivalent expression that cannot be reduced any further under the rules imposed by the form. Then he assumes that this predicate is computable, and can hence be expressed in lambda calculus. Building on earlier work by Kleene and constructing a Gödel numbering for lambda expressions, he constructs a lambda expression <tt>e</tt> that closely follows the proof of Gödel's first incompleteness theorem. If <tt>e</tt> is applied to its own Gödel number, a contradiction results.

Normal forms and confluence
For the untyped lambda calculus, β-reduction as a rewriting rule is neither strongly normalising nor weakly normalising.

However, it can be shown that β-reduction is confluent. (Of course, we are working up to α-conversion, i.e. we consider two normal forms to be equal, if it is possible to α-convert one into the other.)

Therefore, both strongly normalising terms and weakly normalising terms have a unique normal form. For strongly normalising terms, any reduction strategy is guaranteed to yield the normal form, whereas for weakly normalising terms, some reduction strategies may fail to find it.

Anonymous functions
Lambda calculus reifies "functions" and makes them first-class objects, which raises implementation complexity when it is implemented.

For example in Lisp the 'square' function can be expressed as a lambda expression as follows:

The above example is an expression that evaluates to a first-class function. The symbol  creates an anonymous function, given a list of parameter names,   &mdash; just a single argument in this case, and an expression that is evaluated as the body of the function,. The Haskell example is identical. Anonymous functions are sometimes called lambda expressions.

For example Pascal and many other imperative languages have long supported passing subprograms as arguments to other subprograms through the mechanism of function pointers. However, function pointers are not a sufficient condition for functions to be first class datatypes, because a function is a first class datatype if and only if new instances of the function can be created at run-time. And this run-time creation of functions is supported in Smalltalk, Javascript, and more recently in Scala, Eiffel ("agents"), C# ("delegates") and C++11, among others.

Semantics
The fact that lambda calculus terms act as functions on other lambda calculus terms, and even on themselves, led to questions about the semantics of the lambda calculus. Could a sensible meaning be assigned to lambda calculus terms? The natural semantics was to find a set D isomorphic to the function space D → D, of functions on itself. However, no nontrivial such D can exist, by cardinality constraints because the set of all functions from D to D has greater cardinality than D, unless D is a singleton set.

In the 1970s, Dana Scott showed that, if only continuous functions were considered, a set or domain D with the required property could be found, thus providing a model for the lambda calculus.

This work also formed the basis for the denotational semantics of programming languages.