* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
Download Lambda Calculus
Survey
Document related concepts
Transcript
Seminar: Program Analysis and Transformation University of Applied Sciences Rapperswil Lambda Calculus Stefan Oberholzer, [email protected] June 2010 Abstract The λ-calculus is the basis of functional programming languages. Calculi used to dene new aspects of modern functional programming language have the λ-calculus as its basis. This document describes the basic operations of the untyped-λ-calculus and shows how it can be used to describe recursion, boolean logic and calculation with positive integers. 1 Introduction The λ-calculus is a calculus used to dene functions, function applications and recursion. 1.1 History of the λ-calculus The λ-calculus was dened in the early 1930ies by Alonso Church and Haskel B. Curry. Even though at this time the λ-calculus did not have a consistent mathematical model. In 1936 Keene and Rosser proved that all recursive functions can be expressed with the λcalculus and in 1937 Turing showed that the λ-calculus has the same power as a turing-machine. In 1969 Daniel Scott described the rst mathematical model for the λ-calculus . The basic λ-calculus does not dene types, even though Curry (1934) and Church (1940) have described an extension that allows the denition of types. (See [Rev88] and [Bar92]). Nowadays the λ-calculus is the basis of all functional programming languages as e.g. Lisp or Haskell. 1.2 Denition of a calculus A calculus is a formal language and a system of rules that can be used to derive theorems1 from axioms2 . A calculus denes a set of symbols, a grammar, a set of axioms and a set of inference rules. 1 2 A theorem is a statement proven by the basis of prevously established statements. An axiom is a proposition that is not proved but considered to be self-evident. 1 2 λ-calculus basics 2.1 Denition The basic λ-calculus denes only a few constructs. These are the following: 1. variables 2. abstraction 3. applications 4. operators [Chu41]. 2.1.1 Variables The λ-calculus denes three primitive symbols λ, '(' and ')' and an innite list of variables (a, b, c, . . . ) 2.1.2 Abstraction An abstraction is used to dene functions. It has the form λ<variable>.<λ-expression>. This can be seen like an anonymous function with one parameter, where the <variable> denotes the argument and the <λ-expression> denotes the function body. This denition als denes, that a λ-abstraction has always only one parameter. This limitation is not a problem because every function having multiple parameters can be transformed into a series of multiple functions taking a single parameter (see Section 9). 2.1.3 Application An Application is the application of one λ-expression to another and has the form F A. So the function (F ) is the the rst expression (the operator ) and is applied to its argument A in the second expression (the operand ). This implies that the parameter of a function can be both a variable or a function (Both are expressions). 2.1.4 Conclusion of denition As it can be seen in the denition the λ-calculus does not dene any constants, numbers, types, basic functions or function names. So there is in fact only one λ-expression containing anonymous functions and parameters. E.g. (λx.xx)y is the function duplicating the operand which is dened as y . 2.2 Syntactic sugar The λ-calculus denes some syntactic sugar to simplify the expressions and make them more human-readable. 2.2.1 Implicit brackets Without brackets λ-expressions are always read from left to right. For example the expression λx.λy.yx equals the expression λx.(λy.yx). 2 2.2.2 Encapsulated λ-expressions To simplify encapsulated λ-expressions like λx.λy.y the function parameter denitions can be taken together with a single λ sign. For example λx.λy.yx can be written as λxy.yx. 2.2.3 Nominal denitions Church dened a system to name a λ-expression with a symbol [Chu41]. This nominal denitions have the form < Abbreviation >→< λ − expression > < Abbreviation > is the name used for the denition on the right hand side. On the right hand side of the arrow can be any λ-expression. Example E → (λx.xy) denes the abbreviation E for the expression (λx.xy). Using this abbreviation (EE) stands for ((λx.xy)(λx.xy)). 2.2.4 Schematic denition Another form of abbreviations introduced by Church are schematic denitions [Chu41]. Schematic denitions dene the form of expressions and allows a more readable form. As in the case of the nominal denition the schema is on the left side of the arrow and the schematic denition is on the right hand side. The schemantic denition is written in square brackets [] to be able to dier between a schematic denition and a nominal denition. An example of this is [M × N ] → (λa(M (N a))). M and N can be replaced by any variable or abbreviation and thus will also be replaced on the right hand side. Variables on the right side of the arrow that do not occur on the left side are used to dene variables that are not used in the denition. So a stands for the rst variable, b for the second and so on. So the variable names used in the denition are not x and can be changed if a variable is already used in the λ-abstraction using the schematic denition. By using the example schematic denition from above, the expression [I × I] stands for (λa(I(Ia))). In the case of the expression [a × b] a is already used and therefore the occurence in the schema is replaced by the next free variable (c). So the full form of [a × b] is (λc(a(bc))). 3 Free and bound variables The concept of free and bound variables is very important to evaluate λ-expressions. Free variables are like constants. They will not be changed when the expression is evaluated. The bound variables on the other hand are bound by the argument denition of the function and will be replaced when the function is applied to an operand. The free variables in a term E is notated as F V (E). Assume the following expression: λx.xy 3 Formal denition of `free` 1 2 x occurs free in x x occurs free in E F 3 x occurs free in λy.E ⇐⇒ or ⇐⇒ or x occurs free in F x occurs free in E (but not in any other variable or constant x occurs free in E x and y are dierent variables Table 1: Denition of Free [Nil] In this case, x is bound to the λ-expression and will be replaced when the function is applied to any operand. On the other hand y is free and will stay unchanged by applying an operand to the function. If we take the expression x(λx.x) the rst x occurs free because it does not occure in an argument denition while the second x is bound by the λ-expression. The formal denition can be seen in table 1 The defnition 1 says that a variable is free in a λ-expression if the expression is the variable itself. Denition 2 says that a variable is free in a λ-expression if it is free in one of it's sub-expressions. In this case it is important to know that the same variable name can occure bound in one λexpression and free in the other λ-expression. This is because the variable x in one λ-expression is not the same variable x of the other λ-expression. The third denition denes that a variable occurs free in a λ-expression encapsulating another λ-expression if it is not the argument variable of the outer λ-expression or occures free in the inner λ-expression. 4 Renaming variables (α conversion) As the names of variables are arbitrary there must be a way to determine functions that only dier in the name of their bound variables. For example λx.x is equivalent to λy.y , because the result will be the same if both functions are applied to the same operand. It is important to check whether two expressions are equal because this might be required to prevent that variable naming conicts arise when an expression is reduced (see Section 6). The α conversion is used to convert an expression into an equivalent expression with dierent names for the bound variables. The α equivalence is described with the symbol ↔α . For example the expression λx.x is α convertable (↔α ) to λy.y because only the name of the bound variable is dierent. xM There are multiple forms how α conversions can be described. Church uses the syntax SN x to describe the substition of x by N in M [Chu41]. So Sk (λx.xy) ≡ λk.ky . x M. Today the form M [x := N ] is used more often then the form SN 5 Substitution Substitution is used to replace abbreviations and perform β reductions (see section 6). This is done by replacing a free variable in a λ-expression with another λ-expression. 4 The substitution of a term E1 for the variable x in term E2 is written as E2 E1 /v [Met01]. There are the following denitions: v[E/v] ≡ E (1) x[E/v] ≡ x for x 6≡ v (2) (E1 E2 )[E/v] ≡ (E1 [E/v])(E2 [E/v]) (3) λv.E1 [E/v] ≡ λv.E1 (4) (λx.E1 )[E/v] ≡ λx.E1 [E/v] for x 6≡ v and x 6≡ F V (E) (5) (6) The rst three denitions are easy to understand. In the 4. denition (λv.E1 [E/v] ≡ λv.E1 ) the λ-expression E1 is not changed because all occurrences in E1 are bound and therefor no free occurrence can be substituted. The 5. denition denes that a substitution can only be made if the substituted variable is not bound and no free variable in E gets bound after the substitution (x 6≡ F V (E)). 6 Application of functions (β reduction) Up to now only the denition of functions and the transformation of these functions have been dened. The β reduction now denes how the operators can be applied to the operands and a resulting expression can be evaluated [Pie02]. 6.1 Denition of β reduction • A β reduction is notated by the symbol →β • A beta reduction (→β ) is the smallest relation fulllling the following rules: (λx.E1 )E2 →β E1 [E2 /x] ≡ E1 E2 E1 →β E10 E1 E2 →β E10 E2 E2 →β E20 E1 E2 →β E2 E20 E →β E 0 λx.E →β λx.E 0 • An expression in the form (λE1 )E2 can be reduced using a β reduction and is called β − Redex (reducible expression). • A λ-expression that does not contain a β − Redex is in the (β ) normal form. • If EN F is in the normal form and there is a sequence of β reductions (E →β . . . →β EN F ) then EN F is the normal form of E . If the β reduction would lead to variable name conicts, the α conversation has to be done upfront. This can be seen in the following example: (λx.(λy.xy)(xy) →β (λy.xy)[xy/x] 5 As it can be easily seen the substitution is not allowed because the bound variable of the inner λ expression (y ) occurs as free variable in the operand. So the bound variable of the inner λ expression must be renamed. (λy.xy)[xy/x] =α (λz.xz)[xy/z] After this conversion the substitution is allowed. (λz.xz)[xy/z] ≡ (λ.(xy)z) 6.1.1 β reduction with multiple Redex A λ-expression can have multiple Redex at the same time. (E.g. (λx.xkx)((λy.y)(z))). As a result of this there are multiple possible ways to reduce such expressions. It can be shown that the β reduction is conuent3 so each way of reduction leads to the same normal form if there exists a normal form. Figure 1 shows a graph of the possible ways to reduce (λx.xkx)((λy.y)(z)). Figure 1: Example for conuence in β reduction As already mentioned conuence does not mean that a normal form exists. For example the following λ-expression does not have a normal form. (λx.xx)(λx.xx) Reducing this expression would lead to a innite loop always resulting in the same expression. (λx.xx)(λx.xx) →β (xx)[(λx.xx)/x] ≡ (λx.xx)(λx.xx) 7 Functions with the same result (η reduction) η reduction is used to show that two functions are the same regarding their output for any input. The η reduction denes that λx.Ex →η E if x 6∈ F V (E). The η reduction is also conuent. 8 Reduction strategies As it can be seen in the previous chapter the β reduction allows to reduce the same λ-expression in multiple ways. This may lead to a normal form or it does not. This depends on which redex is reduced rst. Multiple concrete reduction strategies have been dened. This chapter describes a few of them. Please be aware that only some well known reduction strategies are explained. There are more reduction strategies available. 3 Conuent means that a term can be rewritten in many ways yielding the same result. 6 8.1 Applicative order This reduction strategy denes that the leftmost and innermost redex is reduced rst. This means that the operands are always reduced before the operator is reduced [Met01]. So the applicative order reduction strategy always reduces every λ-expression at most once. A drawback of it is that it may not get the normal form even if one exists. For example in the following λ-expression the normal form will not be found: (λx.c)((λx.xx)(λx.xx)) →β (λx.c)((λx.xx)(λx.xx)) As it can be seen, trying to evaluate the normal form by using the applicative order might result in a innitive loop even if a normal form would exist. 8.2 Normal order This reduction strategy denes that the leftmost and outermost redex is reduced rst [Pie02]. So the operator is always applied to the operand befor the operand is reduced. The positive aspect of this strategy is that every λ-expression will always be reduced to its normal form if a normal form exists. For example the expression (λx.c)((λx.xx)(λx.xx)) will not be reduced to its normal form using the applicative order strategy but will be reduced to its normal form by using the normal form strategy : (λx.c)((λx.xx)(λx.xx)) →β c The drawback of this strategy is that the same expression might be evaluated multiple times. This can be seen in the following λ-expression: (λx.xx)((λy.y)x) →β ((λy.y)x)((λy.y)x) →β ((λy.y)x)x →β xx The same expression has to be reduced twice. 8.3 Call by name This is like the normal order reduction strategy except that the inner abstractions are not reduced [Pie02]. For example an expression like (λx.(λx.x)x) is in the normal form by using this strategy. 8.4 Call by value Only Redex having a variable on the right hand side are reduced [Pie02]. E.g. (λx.x)(λx.x) is in the normal form by using this reduction strategy while (λx.x)z will be reduced to z . 8.5 Call by need This is like the normal order reduction with the dierence that a mechanism is used to go sure that every Redex is only reduced once. This is done by introducing pointers to the Redex when it is substituted. For example in the case the following abstraction ((λy.y)x) is only reduced once. (λx.xx)((λy.y)x) →β < P OIN T ER − T O(λy.y)x) >< P OIN T ER − T O(λy.y)x) >→β xx 7 9 Currying Currying describes the transformation of a function taking multiple arguments into a series of multiple functions each taking only one argument [Pie02]. E.g. the function f(x, y) can be curried into the function g(x) returning the function h(y). As the λ-calculus can only take a single argument per function this transformation is very important. 9.1 Currying example To have an example of currying the multiplication of numbers can be taken. 5∗3 can be expressed by the function multiply(3, 5). By currying a function taking the rst parameter can be created. We will name this function multiply(3). The return value of this function is another function multiplying the value in its parameter with 3 (multiplyByT hree(y)). The result of multiply(3, 5) can now be determined by applying this function to the parameter 5 (multiplyByT hree(5)). So the full function using currying will be written as (multiply(3))(5)). 10 Calculating with positive integers in the λ-Calculus 10.1 Numerical representation As described in Section 2 the basic λ-calculus does not dene any number representation. The Church-Encoding denes how numbers can be expressed with functions [Chu41]. A number n is represented by applying a given function n-times to an argument. To be able to easily dier 1 1 and 11 a bar is used over the numbers. For example: 0̄ → λf x.x 1̄ → λf x.f x 2̄ → λf x.f (f x) ... n̄ → λf x.f n x In the following the short notation n̄ is used as a short notation of λf x.f n x 10.2 Increment (Successor) The successor function S is dened as: S → λnf x.f (nf x) where n is the number that must be incremented. For example the successor of 3̄ is: S 3̄ ≡ (λnf x.f (nf x))(λf x.f (f (f x))) →β λf x.f ((λf x.f (f (f x)))f x) →β λf x.f ((λx.f (f (f x)))x) →β λf x.f (f (f (f x))) ≡ 4̄ 8 10.3 Decrement (Predecessor) The predecessor function P is dened as: P → λnf x.n(λgh.h(gf ))(λu.x)(λu.u) where n is the number that must be decremented. If n is already 0̄ the result is also 0̄. For example the predecessor of 3̄ is: P 3̄ ≡ (λnf x.n(λgh.h(gf ))(λu.x)(λu.u))(λf x.f (f (f x))) →β λf x.(λf x.f (f (f x)))(λgh.h(gf ))(λu.x)(λu.u) →β λf x.(λx.(λgh.h(gf ))((λgh.h(gf ))((λgh.h(gf ))x))))(λu.x)(λu.u) →β λf x.(λx.(λgh.h(gf ))((λgh.h(gf ))((λh.h(xf )))))(λu.x)(λu.u) →β λf x.(λx.(λgh.h(gf ))((λh.h((λh.h(xf ))f ))))(λu.x)(λu.u) →β λf x.(λx.(λgh.h(gf ))(λh.h(f (xf ))))(λu.x)(λu.u) →β λf x.(λx.(λh.h((λh.h(f (xf )))f )))(λu.x)(λu.u) →β λf x.(λx.(λh.h(f (f (xf )))))(λu.x)(λu.u) →β λf x.(λh.h(f (f ((λu.x)f ))))(λu.u) →β λf x.(λh.h(f (f (x))))(λu.u) →β λf x.(λu.u)(f (f (x))) →β λf x.(f (f (x))) ≡ 2̄ 10.4 Addition The addition function is dened as: A → λnmf x.nf (mf x) where n and m are the numbers that must be summed-up. For example the addition of 3̄ and 2̄ is: A3̄2̄ ≡ λnmf x.(nf (mf x))(λf x.f (f (f x)))(λf x.f (f x)) →β λmf x.(λf x.f (f (f x)))f (mf x)(λf x.f (f x)) →β λmf x.((λx.f (f (f x)))(mf x))(λf x.f (f x)) →β λmf x.(f (f (f (mf x))))(λf x.f (f x))= Add 3 function →β λf x.(f (f (f ((λf x.f (f x))f x)))) →β λf x.(f (f (f ((λx.f (f x))x)))) →β λf x.(f (f (f (f (f x))))) ≡ 5̄ 10.5 Subtraction The subtraction function S is dened as: S → λmn.nP m where n̄ is the number that is subtracted from m̄. If n̄ is bigger than m̄ 0̄ is returned. 9 For example the subtraction of 3̄ − 1̄ is: S 3̄1̄ ≡ (λmn.nP m)(λf x.f (f (f x)))(λf x.f x) →β (λn.nP (λf x.f (f (f x))))(λf x.f x) ≡ (λn.n(λnf x.n(λgh.h(gf ))(λu.x)(λu.u))(λf x.f (f (f x))))(λf x.f x) →β (λf x.f x)(λnf x.n(λgh.h(gf ))(λu.x)(λu.u))(λf x.f (f (f x))) →β (λx.(λnf x.n(λgh.h(gf ))(λu.x)(λu.u))x)(λf x.f (f (f x)) →β (λnf x.n(λgh.h(gf ))(λu.x)(λu.u))((λf x.f (f (f x))) →β λf x.(λf x.f (f (f x)))(λgh.h(gf ))(λu.x)(λu.u) →β λf x.(λx.((λgh.h(gf ))((λgh.h(gf ))((λgh.h(gf ))x)))(λu.x)(λu.u) →β λf x.(λgh.h(gf ))((λgh.h(gf ))((λgh.h(gf ))(λu.x)))(λu.u) →β λf x.(λh.h((λgh.h(gf ))((λgh.h(gf ))(λu.x))f ))(λu.u) →β λf x.(λu.u)((λgh.h(gf ))((λgh.h(gf ))(λu.x))f ) →β λf x.(λgh.h(gf ))((λgh.h(gf ))(λu.x))f →β λf x.(λh.h((λgh.h(gf ))(λu.x)f ))f →β λf x.f ((λgh.h(gf ))(λu.x)f ) →β λf x.f ((λh.h((λu.x)f ))f ) →β λf x.f (f ((λu.x)f )) →β λf x.f (f (x)) ≡ 2̄ 10.6 Multiplication The multiplication function is dened as: M → λnmf.n(mf ) where n and m are the numbers that are multiplied. For example the multiplication of 3̄ and 2̄ is: M 3̄2̄ ≡ λnmf.(n(mf ))(λf x.f (f (f x)))(λf x.f (f x)) →β λmf.(λf x.f (f (f x))(mf ))(λf x.f (f x)) →β λmf.(λx.(mf )((mf )((mf )x)))(λf x.f (f x))= multiply by 3 function →β λf.(λx.((λf x.f (f x))f )(((λf x.f (f x))f )(((λf x.f (f x))f )x))) →β λf.(λx.((λf x.f (f x))f )(((λf x.f (f x))f )((λx.f (f x))x))) →β λf.(λx.((λf x.f (f x))f )(((λf x.f (f x))f )(f (f x)))) →β λf.(λx.((λf x.f (f x))f )((λx.f (f x))(f (f x)))) →β λf.(λx.((λf x.f (f x))f )(f (f (f (f x))))) →β λf.(λx.(λx.f (f x))(f (f (f (f x))))) →β λf.λx.f (f (f (f (f (f x))))) ≡ λf x.f (f (f (f (f (f x))))) ≡ 6̄ 10 10.7 Exponentiation The exponentiation function is dened as: P → λbe.eb where b̄ is the basis and ē the exponent. For example the exponentiation of 3̄2̄ is: P 3̄2̄ ≡ (λbe.eb)(λf x.f (f (f x)))(λf x.f (f x)) →β (λe.e(λf x.f (f (f x)))(λf x.f (f x)) →β (λf x.f (f x))(λf x.f (f (f x))) →β λx.(λf x.f (f (f x)))((λf x.f (f (f x)))x) →α λx.(λf y.f (f (f y)))(λf x.f (f (f x)))x) →β λxy.(λf x.f (f (f x)))(x)((λf x.f (f (f x)))x((λf x.f (f (f x)))xy)) →β λxy.(λf x.f (f (f x)))(x)((λf x.f (f (f x)))x((λf x.f (f (f x)))xy)) →α λxy.(λf i.f (f (f i)))(x)((λf x.f (f (f x)))x((λf x.f (f (f x)))xy)) →β λxy.(λi.x(x(xi)))((λf x.f (f (f x)))x((λf x.f (f (f x)))xy)) →β λxy.x(x(x((λf x.f (f (f x)))(x)((λf x.f (f (f x)))xy)))) →β λxy.x(x(x((λf x.f (f (f x)))(x)((λf x.f (f (f x)))xy)))) →α λxy.x(x(x((λf z.f (f (f z)))(x)((λf x.f (f (f x)))xy)))) →β λxy.x(x(x((λz.x(x(xz)))((λf x.f (f (f x)))xy)))) →β λxy.x(x(x(x(x(x((λf x.f (f (f x)))(x)y)))))) →α λxy.x(x(x(x(x(x((λf k.f (f (f k)))(x)y)))))) →β λxy.x(x(x(x(x(x((λk.x(x(xk)))(y))))))) →β λxy.x(x(x(x(x(x(x(x(xy)))))))) →α λf y.f (f (f (f (f (f (f (f (f y)))))))) →α λf x.f (f (f (f (f (f (f (f (f x)))))))) ≡ 9̄ 11 Boolean Logic This section explains how an IF-statement can be dened in the λ-calculus [Pie02]. To dene this the boolean values T rue and F alse have to be dened rst. 11.1 Boolean : T rue The boolean value T rue is dened using the expression λxy.x. 11.2 Boolean : F alse The boolean value F alse is dened using the expression λxy.y . 11.3 IF-statement Using the denitions of T rue and F alse of the previous subsections an An IF-statement is dened using the following λ-expression λbEE 0 .bEE 0 11 The rst operand must either result in T rue or F alse. As it can be seen in the denition of T rue and F alse the reduced value of this booleans is either the rst or the second operand. 11.4 IF-statement example The following example denes a λ-expression for 'IF F alse THEN E1 ELSE E2 '. (λbxy.bxy)(λxy.y)E1 E2 →β (λxy.(λxy.y)xy)E1 E2 →β (λxy.(λy.y)y)E1 E2 →β (λxy.y)E1 E2 →β (λy.y)E2 →β E2 12 Recursions Showing the problem of recursions in the λ-calculus and explaining the solution for this problem is quite dicult if a pure λ-calculus is taken. Because of this a syntax with more complex functions than the λ-calculus directly supports, is used. One of the best known function requiring recursion is the factorial function f ac n := if (n = 0) then 1 else n ∗ f ac(n − 1). We use this function to explain how recursion can be dened. The problem is that the λ-calculus does not dene named functions that can be used. So a function will never be able to point to itself. By dening a second factorial function taking another factorial function as argument some kind of generic recursion can be dened. This function is dened by the name f ac0 and dened as follows: f ac0 f n := if (n = 0) then 1 else n ∗ f (n − 1) By using this function and passing the f ac function some recursion is still kept (f ac0 (f ac) ≡ f ac). So the required part is a function transforming a function like f ac into another function of the form of the f ac0 function. If this function is known a recursion can be dened easily as shown in subsection 12.1. This function is known as xed point combinator. 12.1 Fixed point combinator (Y-combinator) in the λ-calculus A xed point combinator Y can be expressed by the λ-expression [Pie02]: Y → (λh.(λx.h(xx))(λx.h(xx))) So the expression Y f ac0 can be β reduced as follows: Y f ac0 ≡ (λh.(λx.h(xx))(λx.h(xx)))f ac0 →β (λx.f ac0 (xx))(λx.f ac0 (xx)) →β f ac0 ((λx.f ac0 (xx)) (λx.f ac0 (xx))) ≡ f ac0 (Y f ac0 ) 12 As it can be seen the xed point combinator works and the factorial function (as also any other recursive function) can be expressed by using the Y-combinator. 13 Conclusion The λ-calculus is a powerful calculus. As it is a calculus it should only be used to show that something works because its semantic is not good readable. The examples show how dicult it is to dene a simple operation like subtraction. An implementation of the λ-calculus is rather easy as it follows simple rules. There are already a lot of extensions to it dening types etc. enriching the functionality of the calculus. The λ-calculus or a extension of it is the basic of functional programming languages. A result of this is, that in functional programming languages all expressions can be fully analysed before they have to be executed. This can be done because there are only functions encapsulated in other functions and no global variables. So functional programming languages do not have any problem with concurrent execution at all. This will allow to make applications more easily runnable on a multi processor computer using all available processors. Even imperative programming languages like Java and C# are introducing some functionality of functional programming languages. Personnaly I do not believe that pure functional programming languages will have their break through replacing imperative programming languages. But I think a mixed forms like object oriented programming languages with functional aspects will be etablished. 13 References [Bar92] H. P. Barendregt. Lambda calculi with types. pages 117309, 1992. [Chu41] Alonzo Church. The calculi of Lambda-Conversion. Number 6 in Annals of Mathematics studies. Princeton University Press, 1941. [Met01] André Metzner. Einführung in den lambda-kalkül, Feb 2001. Available online at http: //user.cs.tu-berlin.de/~ame/files/uncompressed/lambda-seminar.pdf. [Nil] Fabian Nilius. Das gefürchtete lambda-kalkül. Website. Available online at http: //www.betoerend.de/dasLandHinterDemEndeDesSinns/lambda/welcome.html. [Pie02] Benjamin C. Pierce. Types and Programming Languages. MIT Press, 2002. [Rev88] G. E. Revesz. Lambda-Calculus, Combinators, and Functional Programming. Cambridge University Press, 1988. 14