Hubbry Logo
Church encodingChurch encodingMain
Open search
Church encoding
Community hub
Church encoding
logo
7 pages, 0 posts
0 subscribers
Be the first to start a discussion here.
Be the first to start a discussion here.
Contribute something
Church encoding
Church encoding
from Wikipedia

In mathematics, Church encoding is a way of representing various data types in the lambda calculus.

In the untyped lambda calculus the only primitive data type are functions, represented by lambda abstraction terms. Types that are usually considered primitive in other notations (such as integers, Booleans, pairs, lists, and tagged unions) are not natively present.

Hence the need arises to have ways to represent the data of these varying types by lambda terms, that is, by functions that are taking functions as their arguments and are returning functions as their results.

The Church numerals are a representation of the natural numbers using lambda notation. The method is named for Alonzo Church, who first encoded data in the lambda calculus this way. It can also be extended to represent other data types in the similar spirit.

This article makes occasional use of the alternative syntax for lambda abstraction terms, where λxyz.N is abbreviated as λxyz.N, as well as the two standard combinators, and , as needed.

Use

[edit]

A straightforward implementation of Church encoding slows some access operations from to , where is the size of the data structure, making Church encoding impractical.[1] Research has shown that this can be addressed by targeted optimizations, but most functional programming languages instead expand their intermediate representations to contain algebraic data types.[2] Nonetheless Church encoding is often used in theoretical arguments, as it is a natural representation for partial evaluation and theorem proving.[1] Operations can be typed using higher-ranked types,[3] and primitive recursion is easily accessible.[1] The assumption that functions are the only primitive data types streamlines many proofs.

Church encoding is complete but only representationally. Additional functions are needed to translate the representation into common data types, for display to people. It is not possible in general to decide if two functions are extensionally equal due to the undecidability of equivalence from Church's theorem. The translation may apply the function in some way to retrieve the value it represents, or look up its value as a literal lambda term. Lambda calculus is usually interpreted as using intensional equality. There are potential problems with the interpretation of results because of the difference between the intensional and extensional definition of equality.

Church numerals

[edit]

Church numerals are the representations of natural numbers under Church encoding. The higher-order function that represents natural number n is a function that maps any function to its n-fold composition. In simpler terms, a numeral represents the number by applying any given function that number of times in sequence, starting from any given starting value:

Church encoding is thus a unary encoding of natural numbers,[4] corresponding to simple counting. Each Church numeral achieves this by construction.

All Church numerals are functions that take two parameters. Church numerals 0, 1, 2, ..., are defined as follows in the lambda calculus:

Starting with 0 not applying the function at all, proceed with 1 applying the function once, 2 applying the function twice in a row, 3 applying the function three times in a row, etc.:

The Church numeral 3 is a chain of three applications of any given function in sequence, starting from some value. The supplied function is first applied to a supplied argument and then successively to its own result. The end result is not the number 3 (unless the supplied parameter happens to be 0 and the function is a successor function). The function itself, and not its end result, is the Church numeral 3. The Church numeral 3 means simply to do something three times. It is an ostensive demonstration of what is meant by "three times".

Calculation with Church numerals

[edit]

Arithmetic operations on numbers produce numbers as their results. In Church encoding, these operations are represented by lambda abstractions which, when applied to Church numerals representing the operands, beta-reduce to the Church numerals representing the results.

Church representation of addition, , uses the identity :

The successor operation, , is obtained by β-reducing the expression "":

Multiplication, , uses the identity :

Thus and , and so by the virtue of Church encoding expressing the n-fold composition, the exponentiation operation is given by

The predecessor operation is a little bit more involved. We need to devise an operation that when repeated times will result in applications of the given function . This is achieved by using the identity function instead, one time only, and then switching back to :

As previously mentioned, is the identity function, . See below for a detailed explanation. This suggests implementing e.g. halving and factorial in the similar fashion,

For example, beta-reduces to , beta-reduces to , and beta-reduces to .

Subtraction, , is expressed by repeated application of the predecessor operation a given number of times, just like addition can be expressed by repeated application of the successor operation a given number of times, etc.:

is the nth tetration operation, , expressing .

Subtraction, directly

[edit]

Just as addition as repeated successor has its counterpart in the direct style, so can subtraction be expressed directly and more efficiently as well:

For example, reduces to an equivalent of .

Table of functions on Church numerals

[edit]
Function Algebra Identity Function definition Lambda expressions
Successor ...
Addition
Multiplication
Exponentiation
Predecessor[a]

Subtraction[a] (Monus) ...

Notes:

  1. ^ a b In the Church encoding,

Predecessor function

[edit]

The predecessor function is given as

This encoding essentially uses the identity

or

An explanation of pred

[edit]

The idea here is as follows. The only thing known to the Church numeral is the numeral itself. Given two arguments and , as usual, the only thing it can do is to apply that numeral to the two arguments, somehow modified so that the n-long chain of applications thus created will have one (specifically, leftmost) in the chain replaced by the identity function:

Here is the modified , and is the modified . Since itself can not be changed, its behavior can only be modified through an additional argument, .

The goal is achieved, then, by passing that additional argument along from the outside in, while modifying it as necessary, with the definitions

Which is exactly what we have in the definition's lambda expression.

Now it is easy enough to see that

i.e. by eta-contraction and then by induction, it holds that

and so on.

Defining pred through pairs

[edit]

The identity above may be coded with the explicit use of pairs. It can be done in several ways, for instance,

The expansion for is:

This is a simpler definition to devise but leads to a more complex lambda expression,

Pairs in the lambda calculus are essentially just extra arguments, whether passing them inside out like here, or from the outside in as in the original definition. Another encoding follows the second variant of the predecessor identity directly,

This way it is already quite close to the original, "outside-in" definition, also creating the chain of s like it does, only in a bit more wasteful way still. But it is very much less wasteful than the previous, definition here. Indeed if we trace its execution we arrive at the new, even more streamlined, yet fully equivalent, definition

which makes it fully clear and apparent that this is all about just argument modification and passing. Its reduction proceeds as

clearly showing what is going on. Still, the original is much preferable since it's working in the top-down manner and is thus able to stop right away if the user-supplied function is short-circuiting. The top-down approach is also used with other definitions like

Division

[edit]

Division of natural numbers may be implemented by,[5]

Calculating takes many beta reductions. Unless doing the reduction by hand, this doesn't matter that much, but it is preferable to not have to do this calculation twice. The simplest predicate for testing numbers is IsZero so consider the condition.

But this condition is equivalent to , not . If this expression is used then the mathematical definition of division given above is translated into function on Church numerals as,

As desired, this definition has a single call to . However the result is that this formula gives the value of .

This problem may be corrected by adding 1 to n before calling divide. The definition of divide is then,

divide1 is a recursive definition. The Y combinator may be used to implement the recursion. Create a new function called div by;

  • In the left hand side
  • In the right hand side

to get,

Then,

where,

Gives,

Or as text, using \ for λ,

divide = (\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))

For example, 9/3 is represented by

divide (\f.\x.f (f (f (f (f (f (f (f (f x))))))))) (\f.\x.f (f (f x)))

Using a lambda calculus calculator, the above expression reduces to 3, using normal order.

\f.\x.f (f (f (x)))

Signed numbers

[edit]

One simple approach for extending Church Numerals to signed numbers is to use a Church pair, containing Church numerals representing a positive and a negative value.[6] The integer value is the difference between the two Church numerals.

A natural number is converted to a signed number by,

Negation is performed by swapping the values.

The integer value is more naturally represented if one of the pair is zero. The OneZero function achieves this condition,

The recursion may be implemented using the Y combinator,

Plus and minus

[edit]

Addition is defined mathematically on the pair by,

The last expression is translated into lambda calculus as,

Similarly subtraction is defined,

giving,

Multiply and divide

[edit]

Multiplication may be defined by,

The last expression is translated into lambda calculus as,

A similar definition is given here for division, except in this definition, one value in each pair must be zero (see OneZero above). The divZ function allows us to ignore the value that has a zero component.

divZ is then used in the following formula, which is the same as for multiplication, but with mult replaced by divZ.

Rational and real numbers

[edit]

Rational and computable real numbers may also be encoded in lambda calculus. Rational numbers may be encoded as a pair of signed numbers. Computable real numbers may be encoded by a limiting process that guarantees that the difference from the real value differs by a number which may be made as small as we need.[7] [8] The references given describe software that could, in theory, be translated into lambda calculus. Once real numbers are defined, complex numbers are naturally encoded as a pair of real numbers.

The data types and functions described above demonstrate that any data type or calculation may be encoded in lambda calculus. This is the Church–Turing thesis.

Translation with other representations

[edit]

Most real-world languages have support for machine-native integers; the church and unchurch functions convert between nonnegative integers and their corresponding Church numerals. The functions are given here in Haskell, where the \ corresponds to the λ of Lambda calculus. Implementations in other languages are similar.

type Church a = (a -> a) -> a -> a

church :: Integer -> Church Integer
church 0 = \f -> \x -> x
church n = \f -> \x -> f (church (n-1) f x)

unchurch :: Church Integer -> Integer
unchurch cn = cn (+ 1) 0

Church Booleans

[edit]

Church Booleans are the Church encoding of the Boolean values true and false. Some programming languages use these as an implementation model for Boolean arithmetic; examples are Smalltalk and Pico.

Boolean logic may be considered as a choice. The Church encoding of true and false are functions of two parameters:

  • true chooses the first parameter.
  • false chooses the second parameter.

The two definitions are known as Church Booleans:

This definition allows predicates (i.e. functions returning logical values) to directly act as if-clauses. A function returning a Boolean, which is then applied to two parameters, returns either the first or the second parameter:

evaluates to then-clause if predicate-x evaluates to true, and to else-clause if predicate-x evaluates to false.

Because true and false choose the first or second parameter they may be combined to provide logic operators. Note that there are multiple possible implementations of not.

Some examples:

Predicates

[edit]

A predicate is a function that returns a Boolean value. The most fundamental predicate is , which returns if its argument is the Church numeral , and if its argument is any other Church numeral:

The following predicate tests whether the first argument is less-than-or-equal-to the second:

,

Because of the identity,

The test for equality may be implemented as,

Church pairs

[edit]

Church pairs are the Church encoding of the pair (two-tuple) type. The pair is represented as a function that takes a function argument. When given its argument it will apply the argument to the two components of the pair. The definition in lambda calculus is,

For example,

List encodings

[edit]

An (immutable) list is constructed from list nodes. The basic operations on the list are;

Function Description
nil Construct an empty list.
isnil Test if list is empty.
cons Prepend a given value to a (possibly empty) list.
head Get the first element of the list.
tail Get the rest of the list.

We give four different representations of lists below:

  • Build each list node from two pairs (to allow for empty lists).
  • Build each list node from one pair.
  • Represent the list using the right fold function.
  • Represent the list using Scott's encoding that takes cases of match expression as arguments

Two pairs as a list node

[edit]

A nonempty list can be implemented by a Church pair;

  • First contains the head.
  • Second contains the tail.

However this does not give a representation of the empty list, because there is no "null" pointer. To represent null, the pair may be wrapped in another pair, giving three values:

  • First - the null pointer (empty list).
  • Second.First contains the head.
  • Second.Second contains the tail.

Using this idea the basic list operations can be defined like this:[9]

Expression Description
The first element of the pair is true meaning the list is null.
Retrieve the null (or empty list) indicator.
Create a list node, which is not null, and give it a head h and a tail t.
second.first is the head.
second.second is the tail.

In a nil node second is never accessed, provided that head and tail are only applied to nonempty lists.

One pair as a list node

[edit]

Alternatively, define[10]

where the definitions like the last one follow the general pattern of the safe use of a list, where and refer to the list's head and tail:

Other operations for one pair as a list node




Represent the list using right fold

[edit]

As an alternative to the encoding using Church pairs, a list can be encoded by identifying it with its right fold function. For example, a list of three elements x, y and z can be encoded by a higher-order function that when applied to a combinator c and a value n returns c x (c y (c z n)). Equivalently, it is an application of the chain of functional compositions of partial applications, (c x c y c z) n.

This list representation can be given type in System F.

The evident correspondence to Church numerals is non-coincidental, as that can be seen as a unary encoding, with natural numbers represented by lists of unit (i.e. non-important) values, e.g. [() () ()], with the list's length serving as the representation of the natural number. Right folding over such lists uses functions which necessarily ignore the element's value, and is equivalent to the chained functional composition, i.e. (c () c () c ()) n = (f f f) n, as is used in Church numerals.

Represent the list using Scott encoding

[edit]

An alternative representation is Scott encoding, which uses the idea of continuations and can lead to simpler code.[11] (see also Mogensen–Scott encoding).

In this approach, we use the fact that lists can be observed using pattern matching expression. For example, using Scala notation, if list denotes a value of type List with empty list Nil and constructor Cons(h, t) we can inspect the list and compute nilCode in case the list is empty and consCode(h, t) when the list is not empty:

list match {
  case Nil        => nilCode
  case Cons(h, t) => consCode(h,t)
}

The list is given by how it acts upon nilCode and consCode. We therefore define a list as a function that accepts such nilCode and consCode as arguments, so that instead of the above pattern match we may simply write:

Let us denote by n the parameter corresponding to nilCode and by c the parameter corresponding to consCode. The empty list is the one that returns the nil argument:

The non-empty list with head h and tail t is given by

More generally, an algebraic data type with alternatives becomes a function with parameters. When the th constructor has arguments, the corresponding parameter of the encoding takes arguments as well.

Scott encoding can be done in untyped lambda calculus, whereas its use with types requires a type system with recursion and type polymorphism. A list with element type E in this representation that is used to compute values of type C would have the following recursive type definition, where '=>' denotes function type:

type List = 
  C =>                    // nil argument
  (E => List => C) =>     // cons argument
  C                       // result of pattern matching

A list that can be used to compute arbitrary types would have a type that quantifies over C. A list generic [clarification needed] in E would also take E as the type argument.

See also

[edit]

References

[edit]
Revisions and contributorsEdit on WikipediaRead on Wikipedia
from Grokipedia
Church encoding is a method developed by for representing various data types and structures, such as natural numbers, booleans, and pairs, purely as lambda terms within the untyped , enabling computation without relying on any built-in primitives beyond function abstraction and application. Introduced at the end of Church's 1933 paper "A Set of Postulates for the Foundation of Logic (Second Paper)," this encoding demonstrates the expressive power of by allowing arithmetic, logic, and data manipulation to be defined via beta-reduction alone. The most prominent example of Church encoding is the representation of natural numbers, known as Church numerals, where the number nn is encoded as the lambda term λfx.fnx\lambda f x. f^n x, a function that applies its first argument ff exactly nn times to its second argument xx. For instance:
  • Zero: 0λfx.x0 \triangleq \lambda f x. x
  • One: 1λfx.fx1 \triangleq \lambda f x. f x
  • Two: 2λfx.f(fx)2 \triangleq \lambda f x. f (f x)
This encoding supports basic arithmetic operations through additional lambda terms; the successor function, for example, is succλnfx.f(nfx)\mathsf{succ} \triangleq \lambda n f x. f (n f x), which increments a numeral by one application. Similarly, addition is defined as plusλmnfx.mf(nfx)\mathsf{plus} \triangleq \lambda m n f x. m f (n f x), composing the applications of two numerals. Beyond numerals, Church encoding extends to booleans, where trueλxy.x\mathsf{true} \triangleq \lambda x y. x and falseλxy.y\mathsf{false} \triangleq \lambda x y. y, functioning as selectors that return one of two arguments based on a condition. Logical operations follow naturally: negation is notλb.b false true\mathsf{not} \triangleq \lambda b. b\ \mathsf{false}\ \mathsf{true}, and conjunction is andλb1b2.b1 b2 false\mathsf{and} \triangleq \lambda b_1 b_2. b_1\ b_2\ \mathsf{false}. Pairs are encoded as pairλabf.fab\mathsf{pair} \triangleq \lambda a b f. f a b, with projections using booleans: fstλp.p true\mathsf{fst} \triangleq \lambda p. p\ \mathsf{true} and sndλp.p false\mathsf{snd} \triangleq \lambda p. p\ \mathsf{false}. Church encoding underscores the universality of , as formalized in Church's system, which Church presented more fully in his 1941 book The Calculi of Lambda-Conversion and used to establish foundational results in , including the equivalence of lambda-definable functions to recursive functions. While powerful for theoretical foundations, such encodings highlight the untyped nature of the original , where ill-formed applications can lead to non-termination or unexpected reductions, influencing later developments in typed variants.

Introduction

Definition and Motivation

Church encoding is a technique in untyped for representing data structures and operations solely through lambda terms, without relying on any primitive types or built-in operations beyond function abstraction and application. In this system, all data—such as booleans, pairs, and natural numbers—and all functions manipulating them are expressed as lambda abstractions, demonstrating the foundational principle that computation can be reduced to the application of anonymous functions. The core syntax of lambda terms includes abstractions of the form λx.M\lambda x.M, where xx is a variable and MM is a lambda term denoting the body of the function, and applications of the form (MN)(M N), where MM and NN are lambda terms representing a function applied to an argument. Computation proceeds via beta-reduction, the rule that substitutes the argument NN for all free occurrences of xx in MM when reducing (λx.M)N(\lambda x.M) N, subject to variable capture avoidance. The primary motivation for Church encoding stems from Alonzo Church's development of in the early as a for the foundations of logic and mathematics, where encodings were introduced to illustrate the calculus's ability to model recursive functions and data without external primitives. By encoding structures like natural numbers (known as Church numerals), booleans, and pairs purely in lambda terms, Church aimed to prove that could express all effectively computable functions, thereby establishing its equivalence to other models of computation and supporting the Church-Turing thesis on the limits of mechanical calculation. This approach highlights the Turing-completeness of , as the encodings enable the definition of arithmetic, logic, and control structures through higher-order functions alone. A simple illustrative example is the encoding of the as λx.x\lambda x.x, which takes any term NN and returns it unchanged upon application ((λx.x)N)((\lambda x.x) N), reducing via beta-reduction to NN. Church encodings were originally developed in Church's 1933 paper and elaborated in his 1941 monograph to rigorously demonstrate the expressive power of in relation to recursive function theory and other foundational systems.

Historical Context

Alonzo Church introduced in the early 1930s as part of his efforts to address foundational issues in logic and mathematics, particularly in relation to the posed by , which sought an algorithm to determine the truth of mathematical statements in . His initial formulation appeared in the 1932 paper "A Set of Postulates for the Foundation of Logic," where served as a system for functional abstraction and application, initially within a typed framework to avoid paradoxes. This work laid the groundwork for using lambda terms to model , evolving from Church's broader investigations into the limits of formal systems during the 1930s. Although the 1933 encoding was presented in Church's simple theory of types, it laid the groundwork for representations in the untyped formalized in 1936. Church first introduced the encoding of natural numbers in his 1933 paper "A Set of Postulates for the Foundation of Logic (Second Paper)". In his 1936 paper "An Unsolvable Problem of Elementary ," he formalized lambda-definability using the untyped and this encoding to demonstrate the undecidability of certain problems in . In this context, Church shifted to an untyped , eliminating restrictive typing from earlier versions to enhance expressive power for defining effective calculability. The encoding allowed him to prove that lambda-definable functions capture intuitive notions of computability, forming the basis of Church's thesis, which posits as a universal , independently paralleling Alan Turing's 1936 machine model. The adoption of Church encoding played a key role in establishing the Turing completeness of lambda calculus, as subsequent proofs showed equivalence between lambda-definable functions and Turing-computable ones. It influenced early developments in recursion theory, notably Stephen Kleene's 1938 recursion theorem, which extended Church's ideas on self-referential computable functions using similar lambda-based notations. Although Church encoding predates Turing machines by several months in its formalization, its core concepts saw no significant revisions after the 1940s, yet it retains foundational relevance in theoretical computer science for illustrating pure functional computation.

Fundamental Encodings

Church Booleans

In Church encoding within the , boolean values are represented as higher-order functions that select one of two arguments based on a , treating booleans uniformly as functional selectors rather than primitive constants. The encoding for true selects the first argument and is defined as the lambda term \trueλt.λf.t\true \triangleq \lambda t. \lambda f. t. Conversely, false selects the second argument and is encoded as \falseλt.λf.f\false \triangleq \lambda t. \lambda f. f. This selector-based representation, originally proposed by , enables the implementation of and logical structures purely through abstraction and application, without relying on built-in data types. Building on these encodings, the conditional operation (if-then-else) is defined as \ifλp.λa.λb.pab\if \triangleq \lambda p. \lambda a. \lambda b. p \, a \, b, where the boolean pp determines whether to return aa (the "then" branch) or bb (the "else" branch) via selection. Standard logical operations follow similarly: negation (not) inverts the boolean by swapping the branches, given by ≜̸λp.p\false\true\not \triangleq \lambda p. p \, \false \, \true; conjunction (and) evaluates the second operand only if the first is true, as \andλp.λq.pq\false\and \triangleq \lambda p. \lambda q. p \, q \, \false; and disjunction (or) short-circuits to true if the first operand is true, defined as \orλp.λq.p\trueq\or \triangleq \lambda p. \lambda q. p \, \true \, q. These compositions exploit the inherent selector mechanism of Church booleans to replicate classical boolean algebra in lambda terms. For example, applying and to true and false yields false through beta-reduction: \and\true\falseβ\and \, \true \, \false \beta-reduces to \true\false\false\true \, \false \, \false, which further reduces to \false\false since true selects its first argument. This reduction sequence highlights how Church booleans facilitate precise, step-by-step evaluation of logical expressions solely via functional application. These foundational encodings underpin extensions to predicates, which test properties using outcomes.

Church Pairs

In the lambda calculus, ordered pairs are encoded using higher-order functions that allow selective access to their components without relying on primitive data types. The pair constructor, denoted as PAIR, is defined as λx.λy.λz.zxy\lambda x. \lambda y. \lambda z. z\, x\, y, which takes two elements xx and yy along with a selector function zz and applies zz to xx and yy. This encoding represents the pair as a function that defers the choice of operation on its components until a projector is provided. To extract the components, two projection functions are used. The first projection, FST, is λp.p(λx.λy.x)\lambda p. p\, (\lambda x. \lambda y. x), which applies the pair pp to a function that selects the first argument, yielding xx. Similarly, the second projection, SND, is λp.p(λx.λy.y)\lambda p. p\, (\lambda x. \lambda y. y), which selects the second argument yy. These projections ensure that pairs behave as composable units, enabling the encoding to support functional manipulation of structured data. For instance, to encode the pair of Church numerals 3 and 4, first form the pair as PAIR applied to the numeral for 3 (λf.λx.f(f(fx))\lambda f. \lambda x. f\, (f\, (f\, x))) and the numeral for 4 (λf.λx.f(f(f(fx)))\lambda f. \lambda x. f\, (f\, (f\, (f\, x)))). Applying FST to this pair reduces to the numeral for 3, while SND yields the numeral for 4, demonstrating how the encoding preserves the distinct identities of the components through beta reduction. This pair encoding can be extended to represent longer tuples by nesting pairs, such as encoding a triple as a pair of one element and another pair. Such constructions form the basis for recursive data definitions in , serving as a foundational building block for more complex structures like lists and trees. Pairs also play a role in implementing operations like the predecessor function by storing intermediate values during computation.

Predicates

In Church encoding, predicates are higher-order functions that take encoded data, such as numerals, and return Church booleans to test specific properties, enabling conditional behavior in pure without built-in primitives. The IsZero predicate determines whether a Church numeral represents zero. It is defined as λn.n(λx.False)True\lambda n. n\, (\lambda x. \mathsf{False})\, \mathsf{True}, where applying the numeral nn to the constant function (λx.False)(\lambda x. \mathsf{False}) nn times yields False\mathsf{False} if n>0n > 0, but returns True\mathsf{True} directly if n=0n = 0. This leverages the iterative nature of Church numerals to fold the test over the encoded count. Predicates for parity, such as IsOdd and IsEven, rely on a operation adapted to Church numerals, which itself requires via a . For instance, IsOdd can be expressed as λn.IsZero(Modn2)\lambda n. \mathsf{IsZero}\, (\mathsf{Mod}\, n\, 2), where Mod computes the through repeated until the is reached. IsEven follows symmetrically as the negation of IsOdd. These definitions highlight the recursive structure needed for non-iterative tests in . Equality testing for Church numerals compares two values mm and nn by checking if their difference is zero in both directions: λm.λn.AND(IsZero(Submn))(IsZero(Subnm))\lambda m. \lambda n. \mathsf{AND}\, (\mathsf{IsZero}\, (\mathsf{Sub}\, m\, n))\, (\mathsf{IsZero}\, (\mathsf{Sub}\, n\, m)). This bidirectional subtraction ensures symmetry, returning True\mathsf{True} only if m=nm = n. These predicates uniquely facilitate branching in lambda calculus computations, as Church booleans themselves act as selectors in conditionals, such as IF(IsZeron)thenelse\mathsf{IF}\, (\mathsf{IsZero}\, n)\, \mathsf{then}\, \mathsf{else}. For example, to compute the factorial of a numeral nn, one might use IsZero to base-case return 1 when n=0n = 0, recursing otherwise on the predecessor.

Numerical Encodings

Church Numerals

Church numerals provide a way to encode the natural numbers within the untyped , representing each nonnegative integer nn through a that performs . Specifically, the Church numeral n\overline{n} is defined as the lambda term λf.λx.fnx\lambda f. \lambda x. f^n x, where fnxf^n x denotes the application of the function ff exactly nn times to the argument xx. This encoding was introduced by at the end of his 1933 paper "A Set of Postulates for the Foundation of Logic (Part II)," where it serves as a basis for representing arithmetic in pure lambda terms. To illustrate, the numeral for zero, 0\overline{0}, is λf.λx.x\lambda f. \lambda x. x, which applies ff zero times and thus returns xx unchanged. For one, 1=λf.λx.fx\overline{1} = \lambda f. \lambda x. f x, applying ff once. The numeral for two is 2=λf.λx.f(fx)\overline{2} = \lambda f. \lambda x. f (f x), and for three, 3=λf.λx.f(f(fx))\overline{3} = \lambda f. \lambda x. f (f (f x)). These examples demonstrate how the structure grows by nesting applications of ff, directly embedding the count nn into the term's form without relying on external data types. Conceptually, a Church numeral n\overline{n} acts as an iterator: given any function ff (interpreted as a successor or step operation) and a base value xx, it computes the result of iterating ff over xx precisely nn times, thereby capturing the iterative essence of natural numbers. This interpretation aligns with the intuitive notion of numbers as repeated applications, allowing lambda calculus to model counting and succession purely functionally. The encoding implicitly realizes the successor operation from Peano arithmetic, where each numeral builds upon the previous by adding one more application of ff, providing a foundation for numerical reasoning in lambda terms. Furthermore, Church numerals relate to fixed-point combinators in enabling recursive definitions over numbers, as iteration can be extended to recursion via such combinators for more complex computations.

Arithmetic Operations

Arithmetic operations on Church numerals are defined purely through higher-order functions in the , leveraging the iterative nature of the numerals to compose applications of a function ff without requiring explicit loops or primitive . This approach demonstrates the expressive power of terms, where numbers themselves act as iterators. Addition of two Church numerals mm and nn, denoted as plus=λm.λn.λf.λx.mf(nfx)\mathsf{plus} = \lambda m.\lambda n.\lambda f.\lambda x. m f (n f x), works by applying ff a total of m+nm + n times to xx: first nn times via the inner application, then mm more times to that result. Specifically, nfxn f x computes the nn-fold application, and mfm f then iterates ff mm times over that intermediate value, yielding the sum. Multiplication, defined as mult=λm.λn.λf.λx.m(nf)x\mathsf{mult} = \lambda m.\lambda n.\lambda f.\lambda x. m (n f) x, treats the nn-fold application of ff as a single composite function nfn f, which is then applied mm times to xx, effectively composing m×nm \times n applications of ff. This encodes the distributive property of multiplication over iterated function application. An equivalent definition using the addition function is multλm.λn.m(plus n)zero\mathsf{mult} \equiv \lambda m.\lambda n. m (\mathsf{plus}\ n) \mathsf{zero}, where plus n\mathsf{plus}\ n is the function that adds nn to its argument, and this is applied mm times starting from zero, enabling multiplication through iterated addition. Exponentiation follows similarly with exp=λm.λn.nm\mathsf{exp} = \lambda m.\lambda n. n m, where nn acts as an iterator that applies the function mm (itself a numeral encoding repeated application) exactly nn times to an implicit base, resulting in mnm^n iterations. Here, the base numeral mm is elevated to serve as the function being iterated, showcasing the higher-order manipulation central to Church encoding. To illustrate, consider the beta-reduction of plus 2 3 f x\mathsf{plus}\ \ulcorner 2 \urcorner\ \ulcorner 3 \urcorner\ f\ x, where 2=λf.λx.f(fx)\ulcorner 2 \urcorner = \lambda f.\lambda x. f (f x) and 3=λf.λx.f(f(fx))\ulcorner 3 \urcorner = \lambda f.\lambda x. f (f (f x)). Substituting yields 2 f (3 f x)=f(f(3 f x))\ulcorner 2 \urcorner\ f\ (\ulcorner 3 \urcorner\ f\ x) = f (f (\ulcorner 3 \urcorner\ f\ x)), and 3 f x=f(f(fx))\ulcorner 3 \urcorner\ f\ x = f (f (f x)), so f(f(f(f(fx))))f (f (f (f (f x)))), which is precisely 5 f x\ulcorner 5 \urcorner\ f\ x. This step-by-step reduction confirms the operation without auxiliary constructs.

Successor and Predecessor Functions

The for Church numerals, denoted as succ\mathsf{succ}, increments a numeral nn by applying its function one additional time. It is defined as succ=λn.λf.λx.f(nfx)\mathsf{succ} = \lambda n . \lambda f . \lambda x . f (n f x), which effectively inserts one more application of ff to the base value xx encoded by nn. This construction preserves the iterative nature of Church numerals, where succ n\mathsf{succ}\ n represents the numeral for n+1n+1. Defining a predecessor function, denoted pred\mathsf{pred}, presents significant challenges in the untyped lambda calculus because Church numerals lack a direct mechanism for decrementing; instead, numerical values are built through repeated function application, requiring indirect simulation via iteration to "count down." To overcome this, pred\mathsf{pred} leverages Church pairs to track intermediate values during iteration, encoding the process such that applying the numeral nn times to an initial pair yields a final pair whose second component is nn and first is n1n-1. Specifically, pred=λn.first(n next (pair zero zero))\mathsf{pred} = \lambda n . \mathsf{first} (n\ \mathsf{next}\ (\mathsf{pair}\ \mathsf{zero}\ \mathsf{zero})), where next=λp.pair (second p) (succ (second p))\mathsf{next} = \lambda p . \mathsf{pair}\ (\mathsf{second}\ p)\ (\mathsf{succ}\ (\mathsf{second}\ p)), pair=λx.λy.λz.z x y\mathsf{pair} = \lambda x . \lambda y . \lambda z . z\ x\ y, first=λp.p true\mathsf{first} = \lambda p . p\ \mathsf{true}, and second=λp.p false\mathsf{second} = \lambda p . p\ \mathsf{false}. This approach uses pairs, previously defined in Church encoding, to maintain a running predecessor while incrementing a counter. For example, applying pred\mathsf{pred} to the Church numeral 2=λf.λx.f(fx)2 = \lambda f . \lambda x . f (f x) begins with the pair (zero,zero)(\mathsf{zero}, \mathsf{zero}). The first iteration yields (zero,one)(\mathsf{zero}, \mathsf{one}), and the second yields (one,2)(\mathsf{one}, 2); extracting the first component returns one\mathsf{one}. For n=0n = 0, the result is zero\mathsf{zero}, ensuring consistency.

Advanced Numerical Representations

Signed Numbers

Signed integers in Church encoding are represented as pairs consisting of a Church boolean indicating the sign and a Church numeral representing the absolute value or magnitude. The true boolean, defined as λt.λf.t\lambda t.\lambda f. t, denotes a positive sign, while the false boolean, λt.λf.f\lambda t.\lambda f. f, denotes a negative sign. For instance, the positive integer +3 is encoded as the pair (true, 3), where 3 is the Church numeral λf.λx.f(f(fx))\lambda f.\lambda x. f (f (f x)), and -3 as (false, 3). This pair-based approach leverages the existing encodings of s and numerals to handle negatives purely within the calculus, without introducing primitive integer operations. The of a signed ss is obtained by projecting the second component of the pair, effectively discarding the sign: λs.second s\lambda s. \text{second } s. To negate a signed , the sign is flipped using a function on booleans, such as Neg=λb.b false true\text{Neg} = \lambda b. b\ \mathsf{false}\ \mathsf{true}, yielding λs.pair (Neg (first s))(second s)\lambda s. \text{pair } (\text{Neg } (\text{first } s)) (\text{second } s). For example, applying to +3 produces (false, 3), or -3. This enables basic manipulations of signed representations while preserving the functional nature of Church encodings. Comparisons between signed integers, such as determining if one is greater than another, account for both signs and magnitudes. The greater-than function can be defined by first comparing signs: if both are positive or both negative, compare magnitudes using unsigned comparison; if signs differ, the positive one is greater unless its magnitude is zero. This adapts the unsigned comparison from natural number arithmetic to the signed domain by conditioning on the sign booleans. A key advantage of this encoding is its ability to support full integer arithmetic, including operations on negatives, solely through lambda terms. For addition, magnitudes are adjusted conditionally based on signs: if signs match, add the magnitudes and retain the sign; if they differ, subtract the smaller magnitude from the larger and assign the sign of the larger. For example, adding +2, encoded as (true, 2), and -1, as (false, 1), involves subtracting 1 from 2 (yielding magnitude 1) and assigning the positive sign, resulting in +1. Such operations build on magnitude computations from unsigned arithmetic, extended via sign handling.

Rational and Real Numbers

In Church encoding, rational numbers are represented as pairs of Church numerals for the numerator and denominator, assuming positive denominators and allowing signed numerators to handle negative values as defined in signed number encodings. This encoding leverages the Church pair construction, where a rational pq\frac{p}{q} is the term λz.zpq\lambda z. z \, p \, q, with pp and qq as Church numerals. Arithmetic operations on rationals are defined by composing the encoded integer operations. For addition, the sum of r1s1\frac{r_1}{s_1} and r2s2\frac{r_2}{s_2} is encoded as λr1.λs1.λr2.λs2.\lambda r_1. \lambda s_1. \lambda r_2. \lambda s_2. pair (Add(Mulr1s2)(Mulr2s1))(Muls1s2)(\mathsf{Add} \, (\mathsf{Mul} \, r_1 \, s_2) \, (\mathsf{Mul} \, r_2 \, s_1)) \, (\mathsf{Mul} \, s_1 \, s_2), where Add\mathsf{Add} and Mul\mathsf{Mul} are the Church-encoded addition and multiplication on numerals. Similar compositions define multiplication as λr1.λs1.λr2.λs2.\lambda r_1. \lambda s_1. \lambda r_2. \lambda s_2. pair (Mulr1r2)(Muls1s2)(\mathsf{Mul} \, r_1 \, r_2) \, (\mathsf{Mul} \, s_1 \, s_2) and other operations. To normalize a fraction pq\frac{p}{q} to lowest terms, compute the greatest common divisor g=gcd(p,q)g = \gcd(|p|, q) using a recursively defined Euclidean algorithm encoded via the fixed-point combinator in lambda calculus, then divide both by gg. For example, the rational 12\frac{1}{2} is the pair of Church numerals 1 and 2. Adding 13\frac{1}{3}, represented as the pair of 1 and 3, yields the pair of 5 and 6 before normalization, or 56\frac{5}{6} after applying the GCD (which is 1). Real numbers in Church encoding are more complex due to their continuity and require representations that capture infinite precision, often linking to computable reals. One approach uses Dedekind cuts, encoding a real as a pair of lower and upper sets of rationals: the lower set LL contains all rationals strictly less than the real, and the upper set UU contains all rationals strictly greater, with LL and UU disjoint, nonempty, and satisfying the Dedekind properties (no maximum in LL, no minimum in UU). These sets are represented as lambda terms acting as predicates on rationals: the lower cut δ\delta is λd.d<a\lambda d. \, d < a (returning a Church boolean true if rational dd is in LL), and the upper cut υ\upsilon is λu.a<u\lambda u. \, a < u, forming the pair (δ,υ)(\delta, \upsilon). This encoding ensures exact representation through the lambda terms' computational content, as explored in Abstract Stone Duality (ASD), where reals form a subspace of pairs of rational predicates with infinite precision for arithmetic operations extended continuously from rationals. Computable reals arise when the predicates are computable functions, aligning with Bauer's framework for exact real computation in lambda-based models, avoiding approximation errors inherent in finite representations. Alternatively, reals can be encoded via Cauchy sequences of rationals, represented as infinite streams (encoded recursively) converging to the real within specified error bounds, though this requires handling limits through fixed-point recursion.

Translations to Other Representations

Church encodings of natural numbers can be translated to other numeral systems to facilitate with different computational paradigms or to leverage alternative representations for efficiency or expressiveness. One common translation maps Church numerals to binary representations, where individual bits are encoded as Church booleans (true for 1 and false for 0), and the numeral itself is represented as a of these bits constructed via iterated operations on pairs. For instance, the Church numeral for 3, which applies its function three times, can be converted to the binary representation 11 by building a bit as the pair of true and the pair of true and false, effectively encoding the value through the structure of the rather than repeated application. This approach allows for more compact storage in systems supporting binary operations, as demonstrated in left-associated binary numeral systems within . Another mapping exists from Peano numerals, defined inductively with zero and a , to Church numerals, where the Peano successor directly corresponds to the Church successor that increments by wrapping an additional . This translation preserves the iterative structure of natural numbers, linking the inductive definition in Peano arithmetic to the functional iteration in lambda terms, and enables proofs of equivalence between the two systems through fold operations on data types. Church numerals also align closely with von Neumann ordinals from , where the numeral nn is represented as λf.λx.fnx\lambda f. \lambda x. f^n x, mirroring the von Neumann construction of ordinals as transitive sets containing all smaller ordinals, but adapted to functional form with explicit over applications rather than set membership. This similarity highlights the expressive power of in modeling set-theoretic constructs without primitive sets. These translations underscore the universality of Church encodings, as they can be converted to alternative forms like Scott numerals—where numbers are case analyzers distinguishing zero from successors—using fixed-point combinators to bridge the iterative Church style with the eliminative Scott approach, enabling seamless operations across encodings. For binary lists, such conversions may reference encodings briefly to handle the cons-based structure.

Data Structure Encodings

List Encodings

In Church encoding, lists are represented functionally using higher-order terms that capture their recursive structure through iteration or folding, allowing operations to be defined uniformly without primitive data types. The empty list, denoted as nil, is encoded as the lambda term λc.λn.n\lambda c. \lambda n. n, which selects the neutral element nn when applied to a cc and neutral nn, effectively acting like the Church false in selection but enabling an empty-list check to behave as true via λl.l(λh.λt.false)true\lambda l. l (\lambda h. \lambda t. \text{false}) \text{true}. The constructor cons, which prepends an element hh (head) to a list tt (tail), is defined as λh.λt.λc.λn.ch(tcn)\lambda h. \lambda t. \lambda c. \lambda n. c\, h\, (t\, c\, n). This encoding represents the list as a right fold, where applying the list to a combining function cc and neutral nn iterates cc over each head element, starting from the rightmost (building right-associatively), thus processing the list in a functional manner without explicit recursion. For example, the list consisting of elements aa followed by bb followed by nil would apply ca(cbn)c\, a\, (c\, b\, n). The head operation extracts the first element of a non-empty list and is encoded as λl.l(λh.λt.h)\lambda l. l\, (\lambda h. \lambda t. h)\, \bot, where \bot is an error term or default value invoked on nil (e.g., yielding an undefined or exceptional result). Similarly, the tail operation returns the rest of the list and is given by λl.l(λh.λt.t)\lambda l. l\, (\lambda h. \lambda t. t)\, \bot, again using \bot for the empty case. These definitions leverage the fold structure: for a list l=conshtl = \text{cons}\, h\, t, head reduces to hh by selecting the head in the cons case, while tail reduces to tt. An alternative pair-based encoding composes lists from nested Church pairs, where cons hth\, t forms a pair (h,t)(h, t), resulting in right-nested structures like ((a,(b,nil)))((a, (b, \text{nil}))) for a list [a,b][a, b], with head and tail as the pair's first and second projections, respectively. This builds on Church pairs as foundational combinators but emphasizes functional processing in the primary fold-based approach.

Scott Encoding for Lists

Scott encoding provides an alternative representation of lists in the untyped lambda calculus that directly mirrors the structure of algebraic data types, enabling pattern matching through higher-order functions rather than relying on pairs for cons cells. In this encoding, a list is treated as a function that accepts two arguments: a cons case handler cc (of type head × tail → result) and a nil case handler nn (of type result), applying the appropriate one based on the list's structure. This approach is isomorphic to the inductive type for lists, List A=1+A×List A\text{List } A = 1 + A \times \text{List } A, where the empty list corresponds to the unit and non-empty lists to the product. The empty list, nil, is encoded as λc.λn.n\lambda c. \lambda n. n, which selects the nil handler when applied. A non-empty list cons hh tt (with head hh and tail tt) is encoded as λc.λn.cht\lambda c. \lambda n. c \, h \, t, invoking the cons handler with the head and tail. This functional representation facilitates direct recursion over the data structure, as the list itself drives the case analysis without needing additional projectors or deconstructors. Common operations on Scott-encoded lists leverage this pattern-matching capability. The right fold, foldr, which accumulates a value from the end of the list using a ff (of type A×BBA \times B \to B) and initial value zz (of type BB), is defined as λl.λz.λf.lfz\lambda l. \lambda z. \lambda f. l \, f \, z. For the empty list, this reduces to zz; for a non-empty list, it applies ff to the head and the fold over the tail. Similarly, the map function, which applies a ff (of type AAA \to A) to each element, is λl.λf.l(λh.λt.cons(fh)t)nil\lambda l. \lambda f. l \, (\lambda h. \lambda t. \text{cons} \, (f \, h) \, t) \, \text{nil}, reconstructing the list by transforming each head while preserving the structure. These definitions exploit the Scott encoding's inherent recursion support, making it more straightforward for compared to pair-based encodings. For instance, consider a list encoding the numerals [1, 2], represented as cons1(cons2nil)\text{cons} \, \mathbf{1} \, (\text{cons} \, \mathbf{2} \, \text{nil}), where 1\mathbf{1} and 2\mathbf{2} are Church numerals. Applying map with the successor function succ\text{succ} (defined as λn.nadd1\lambda n. n \, \text{add} \, \mathbf{1}, where add is addition) yields cons2(cons3nil)\text{cons} \, \mathbf{2} \, (\text{cons} \, \mathbf{3} \, \text{nil}), corresponding to [2, 3], through successive beta-reductions that transform each element.

References

Add your contribution
Related Hubs
Contribute something
User Avatar
No comments yet.