In
combinatory logic
Combinatory logic is a notation to eliminate the need for quantified variables in mathematical logic. It was introduced by Moses Schönfinkel and Haskell Curry, and has more recently been used in computer science as a theoretical model of com ...
for
computer science
Computer science is the study of computation, information, and automation. Computer science spans Theoretical computer science, theoretical disciplines (such as algorithms, theory of computation, and information theory) to Applied science, ...
, a fixed-point combinator (or fixpoint combinator)
is a
higher-order function In mathematics and computer science, a higher-order function (HOF) is a function that does at least one of the following:
* takes one or more functions as arguments (i.e. a procedural parameter, which is a parameter of a procedure that is itself ...
(i.e., a
function which takes a function as
argument
An argument is a series of sentences, statements, or propositions some of which are called premises and one is the conclusion. The purpose of an argument is to give reasons for one's conclusion via justification, explanation, and/or persu ...
) that returns some ''
fixed point'' (a value that is mapped to itself) of its argument function, if one exists.
Formally, if
is a fixed-point combinator and the function
has one or more fixed points, then
is one of these fixed points, i.e.,
:
Fixed-point combinators can be defined in the
lambda calculus
In mathematical logic, the lambda calculus (also written as ''λ''-calculus) is a formal system for expressing computability, computation based on function Abstraction (computer science), abstraction and function application, application using var ...
and in
functional programming
In computer science, functional programming is a programming paradigm where programs are constructed by Function application, applying and Function composition (computer science), composing Function (computer science), functions. It is a declarat ...
languages, and provide a means to allow for
recursive definitions.
''Y'' combinator in lambda calculus
In the classical untyped
lambda calculus
In mathematical logic, the lambda calculus (also written as ''λ''-calculus) is a formal system for expressing computability, computation based on function Abstraction (computer science), abstraction and function application, application using var ...
, every function has a fixed point. A particular implementation of
is
Haskell Curry's paradoxical combinator ''Y'', given by
[Throughout this article, the syntax rules given in Lambda calculus#Notation are used, to save parentheses.][According to Barendregt p.132, the name originated from Curry.]
:
(Here using the standard notations and conventions of lambda calculus: ''Y'' is a function that takes one argument ''f'' and returns the entire expression following the first period; the expression
denotes a function that takes one argument ''x'', thought of as a function, and returns the expression
, where
denotes ''x'' applied to itself. Juxtaposition of expressions denotes
function application
In mathematics, function application is the act of applying a function to an argument from its domain so as to obtain the corresponding value from its range. In this sense, function application can be thought of as the opposite of function abs ...
, is left-associative, and has higher precedence than the period.)
Verification
The following calculation verifies that
is indeed a fixed point of the function
:
:
The lambda term
may not, in general,
β-reduce to the term
. However, both terms β-reduce to the same term, as shown.
Uses
Applied to a function with one variable, the ''Y'' combinator usually does not terminate. More interesting results are obtained by applying the ''Y'' combinator to functions of two or more variables. The added variables may be used as a counter, or index. The resulting function behaves like a ''while'' or a ''for'' loop in an imperative language.
Used in this way, the ''Y'' combinator implements simple
recursion
Recursion occurs when the definition of a concept or process depends on a simpler or previous version of itself. Recursion is used in a variety of disciplines ranging from linguistics to logic. The most common application of recursion is in m ...
. The lambda calculus does not allow a function to appear as a term in its own definition as is possible in many
programming language
A programming language is a system of notation for writing computer programs.
Programming languages are described in terms of their Syntax (programming languages), syntax (form) and semantics (computer science), semantics (meaning), usually def ...
s, but a function can be passed as an argument to a higher-order function that applies it in a recursive manner.
The ''Y'' combinator may also be used in implementing
Curry's paradox
Curry's paradox is a paradox in which an arbitrary claim ''F'' is proved from the mere existence of a sentence ''C'' that says of itself "If ''C'', then ''F''". The paradox requires only a few apparently-innocuous logical deduction rules. Since '' ...
. The heart of Curry's paradox is that untyped lambda calculus is unsound as a deductive system, and the ''Y'' combinator demonstrates this by allowing an anonymous expression to represent zero, or even many values. This is inconsistent in mathematical logic.
Example implementations
An example implementation of ''Y'' in the language
R is presented below:
Y <- \(f)
This can then be used to implement factorial as follows:
fact <- \(f) \(n)
if (n 0) 1 else n * f(n - 1)
Y(fact)(5) # yields 5! = 120
Y is only needed when function names are absent. Substituting all the definitions into one line so that function names are not required gives:
(\(f) (\(x) f(x(x)))(\(x) f(x(x)))) (\(f) \(n) if (n 0) 1 else n * f(n - 1)) (5)
This works because R uses
lazy evaluation
In programming language theory, lazy evaluation, or call-by-need, is an evaluation strategy which delays the evaluation of an Expression (computer science), expression until its value is needed (non-strict evaluation) and which avoids repeated eva ...
.
Languages that use
strict evaluation, such as
Python,
C++, and other
strict programming languages, can often express Y; however, any implementation is useless in practice since it
loops indefinitely until terminating via a
stack overflow
In software, a stack overflow occurs if the call stack pointer exceeds the stack bound. The call stack may consist of a limited amount of address space, often determined at the start of the program. The size of the call stack depends on many fa ...
.
Fixed-point combinator
The Y combinator is an implementation of a fixed-point combinator in lambda calculus. Fixed-point combinators may also be easily defined in other functional and imperative languages. The implementation in lambda calculus is more difficult due to limitations in lambda calculus.
The fixed-point combinator may be used in a number of different areas:
* General
mathematics
Mathematics is a field of study that discovers and organizes methods, Mathematical theory, theories and theorems that are developed and Mathematical proof, proved for the needs of empirical sciences and mathematics itself. There are many ar ...
* Untyped
lambda calculus
In mathematical logic, the lambda calculus (also written as ''λ''-calculus) is a formal system for expressing computability, computation based on function Abstraction (computer science), abstraction and function application, application using var ...
*
Typed lambda calculus
*
Functional programming
In computer science, functional programming is a programming paradigm where programs are constructed by Function application, applying and Function composition (computer science), composing Function (computer science), functions. It is a declarat ...
*
Imperative programming
In computer science, imperative programming is a programming paradigm of software that uses Statement (computer science), statements that change a program's state (computer science), state. In much the same way that the imperative mood in natural ...
Fixed-point combinators may be applied to a range of different functions, but normally will not terminate unless there is an extra parameter. When the function to be fixed refers to its parameter, another call to the function is invoked, so the calculation never gets started. Instead, the extra parameter is used to trigger the start of the calculation.
The type of the fixed point is the return type of the function being fixed. This may be a real or a function or any other type.
In the untyped lambda calculus, the function to apply the fixed-point combinator to may be expressed using an encoding, like
Church encoding
In mathematics, Church encoding is a means of representing data and operators in the lambda calculus. The Church numerals are a representation of the natural numbers using lambda notation. The method is named for Alonzo Church, who first encoded d ...
. In this case particular lambda terms (which define functions) are considered as values. "Running" (beta reducing) the fixed-point combinator on the encoding gives a lambda term for the result which may then be interpreted as fixed-point value.
Alternately, a function may be considered as a lambda term defined purely in lambda calculus.
These different approaches affect how a mathematician and a programmer may regard a fixed-point combinator. A mathematician may see the Y combinator applied to a function as being an expression satisfying the fixed-point equation, and therefore a solution.
In contrast, a person only wanting to apply a fixed-point combinator to some general programming task may see it only as a means of implementing recursion.
Values and domains
Many functions do not have any fixed points, for instance
with
. Using
Church encoding
In mathematics, Church encoding is a means of representing data and operators in the lambda calculus. The Church numerals are a representation of the natural numbers using lambda notation. The method is named for Alonzo Church, who first encoded d ...
, natural numbers can be represented in lambda calculus, and this function ''f'' can be defined in lambda calculus. However, its
domain will now contain ''all'' lambda expressions, not just those representing natural numbers. The Y combinator, applied to ''f'', will yield a fixed-point for ''f'', but this fixed-point won't represent a
natural number
In mathematics, the natural numbers are the numbers 0, 1, 2, 3, and so on, possibly excluding 0. Some start counting with 0, defining the natural numbers as the non-negative integers , while others start with 1, defining them as the positive in ...
. If trying to compute ''Y f'' in an actual programming language, an infinite loop will occur.
Function versus implementation
The fixed-point combinator may be defined in mathematics and then implemented in other languages. General mathematics defines a function based on its
extensional properties. That is, two functions are equal if they perform the same mapping. Lambda calculus and programming languages regard function identity as an
intensional property. A function's identity is based on its implementation.
A lambda calculus function (or term) is an implementation of a mathematical function. In the lambda calculus there are a number of combinators (implementations) that satisfy the mathematical definition of a fixed-point combinator.
Definition of the term "combinator"
Combinatory logic
Combinatory logic is a notation to eliminate the need for quantified variables in mathematical logic. It was introduced by Moses Schönfinkel and Haskell Curry, and has more recently been used in computer science as a theoretical model of com ...
is a
higher-order function In mathematics and computer science, a higher-order function (HOF) is a function that does at least one of the following:
* takes one or more functions as arguments (i.e. a procedural parameter, which is a parameter of a procedure that is itself ...
s theory. A
combinator is a ''closed'' lambda expression, meaning that it has no
free variables
In mathematics, and in other disciplines involving formal languages, including mathematical logic and computer science, a variable may be said to be either free or bound. Some older books use the terms real variable and apparent variable for f ...
. The combinators may be combined to direct values to their correct places in the expression without ever naming them as variables.
Recursive definitions and fixed-point combinators
Fixed-point combinators can be used to implement
recursive definition
In mathematics and computer science, a recursive definition, or inductive definition, is used to define the elements in a set in terms of other elements in the set ( Aczel 1977:740ff). Some examples of recursively definable objects include fact ...
of functions. However, they are rarely used in practical programming.
Strongly normalizing type system
In computer programming, a type system is a logical system comprising a set of rules that assigns a property called a ''type'' (for example, integer, floating point, string) to every '' term'' (a word, phrase, or other set of symbols). Usu ...
s such as the
simply typed lambda calculus
The simply typed lambda calculus (), a form
of type theory, is a typed interpretation of the lambda calculus with only one type constructor () that builds function types. It is the canonical and simplest example of a typed lambda calculus. The ...
disallow non-termination and hence fixed-point combinators often cannot be assigned a type or require complex type system features. Furthermore fixed-point combinators are often inefficient compared to other strategies for implementing recursion, as they require more function reductions and construct and take apart a tuple for each group of mutually recursive definitions.
The factorial function
The
factorial function provides a good example of how a fixed-point combinator may be used to define recursive functions. The standard recursive definition of the factorial function in mathematics can be written as
:
where ''n'' is a non-negative integer.
Implementing this in lambda calculus, where integers are represented using
Church encoding
In mathematics, Church encoding is a means of representing data and operators in the lambda calculus. The Church numerals are a representation of the natural numbers using lambda notation. The method is named for Alonzo Church, who first encoded d ...
, encounters the problem that the lambda calculus disallows the name of a function ('fact') to be used in the function's definition. This can be circumvented using a fixed-point combinator
as follows.
Define a function ''F'' of two arguments ''f'' and ''n'':
:
(Here
is a function that takes two arguments and returns its first argument if ''n''=0, and its second argument otherwise;
evaluates to ''n''-1.)
Now define
. Then
is a fixed-point of ''F'', which gives
:
as desired.
Fixed-point combinators in lambda calculus
The Y combinator, discovered by
Haskell Curry, is defined as
:
Other fixed-point combinators
In untyped lambda calculus fixed-point combinators are not especially rare. In fact there are infinitely many of them.
In 2005 Mayer Goldberg showed that the set of fixed-point combinators of untyped lambda calculus is
recursively enumerable
In computability theory, a set ''S'' of natural numbers is called computably enumerable (c.e.), recursively enumerable (r.e.), semidecidable, partially decidable, listable, provable or Turing-recognizable if:
*There is an algorithm such that the ...
.
[Goldberg, 2005]
The Y combinator can be expressed in the
SKI-calculus as
:
Additional combinators (
B, C, K, W system) allow for much shorter encodings. With
the self-application combinator, since
and
, the above becomes
:
The shortest fixed-point combinator in the SK-calculus using S and K combinators only, found by
John Tromp, is
:
although note that it is not in normal form, which is longer. This combinator corresponds to the lambda expression
:
The following fixed-point combinator is simpler than the Y combinator, and β-reduces into the Y combinator; it is sometimes cited as the Y combinator itself:
:
Another common fixed-point combinator is the Turing fixed-point combinator (named after its discoverer,
Alan Turing
Alan Mathison Turing (; 23 June 1912 – 7 June 1954) was an English mathematician, computer scientist, logician, cryptanalyst, philosopher and theoretical biologist. He was highly influential in the development of theoretical computer ...
):
:
Its advantage over
is that
beta-reduces to
,
[
]
whereas
and
only beta-reduce to a common term.
also has a simple call-by-value form:
:
The analog for
mutual recursion is a ''polyvariadic fix-point combinator'', which may be denoted Y*.
Strict fixed-point combinator
In a
strict programming language the Y combinator will expand until
stack overflow
In software, a stack overflow occurs if the call stack pointer exceeds the stack bound. The call stack may consist of a limited amount of address space, often determined at the start of the program. The size of the call stack depends on many fa ...
, or never halt in case of
tail call optimization. The Z combinator will work in
strict languages (also called eager languages, where applicative evaluation order is applied). The Z combinator has the next argument defined explicitly, preventing the expansion of
in the right-hand side of the definition:
:
and in lambda calculus it is an
eta-expansion of the ''Y'' combinator:
:
Non-standard fixed-point combinators
If F is a fixed-point combinator in untyped lambda calculus, then there is:
:
Terms that have the same
Böhm tree as a fixed-point combinator, i.e., have the same infinite extension
, are called ''non-standard fixed-point combinators''. Any fixed-point combinator is also a non-standard one, but not all non-standard fixed-point combinators are fixed-point combinators because some of them fail to satisfy the fixed-point equation that defines the "standard" ones. These combinators are called ''strictly non-standard fixed-point combinators''; an example is the following combinator:
:
where
:
:
since
:
where
are modifications of
created on the fly which add
instances of
at once into the chain while being replaced with
.
The set of non-standard fixed-point combinators is not
recursively enumerable
In computability theory, a set ''S'' of natural numbers is called computably enumerable (c.e.), recursively enumerable (r.e.), semidecidable, partially decidable, listable, provable or Turing-recognizable if:
*There is an algorithm such that the ...
.
[
]
Implementation in other languages
The Y combinator is a particular implementation of a fixed-point combinator in lambda calculus. Its structure is determined by the limitations of lambda calculus. It is not necessary or helpful to use this structure in implementing the fixed-point combinator in other languages.
Simple examples of fixed-point combinators implemented in some programming paradigm
A programming paradigm is a relatively high-level way to conceptualize and structure the implementation of a computer program. A programming language can be classified as supporting one or more paradigms.
Paradigms are separated along and descri ...
s are given below.
Lazy functional implementation
In a language that supports lazy evaluation
In programming language theory, lazy evaluation, or call-by-need, is an evaluation strategy which delays the evaluation of an Expression (computer science), expression until its value is needed (non-strict evaluation) and which avoids repeated eva ...
, as in Haskell
Haskell () is a general-purpose, statically typed, purely functional programming language with type inference and lazy evaluation. Designed for teaching, research, and industrial applications, Haskell pioneered several programming language ...
, it is possible to define a fixed-point combinator using the defining equation of the fixed-point combinator which is conventionally named fix
. Since Haskell has lazy data type
In computer science and computer programming, a data type (or simply type) is a collection or grouping of data values, usually specified by a set of possible values, a set of allowed operations on these values, and/or a representation of these ...
s, this combinator can also be used to define fixed points of data constructors (and not only to implement recursive functions). The definition is given here, followed by some usage examples. In Hackage, the original sample is:
fix, fix' :: (a -> a) -> a
fix f = let x = f x in x -- Lambda dropped. Sharing.
-- Original definition in Data.Function.
-- alternative:
fix' f = f (fix' f) -- Lambda lifted. Non-sharing.
fix (\x -> 9) -- this evaluates to 9
fix (\x -> 3:x) -- evaluates to the lazy infinite list ,3,3,...
fact = fix fac -- evaluates to the factorial function
where fac f 0 = 1
fac f x = x * f (x-1)
fact 5 -- evaluates to 120
Strict functional implementation
In a strict functional language, as illustrated below with OCaml
OCaml ( , formerly Objective Caml) is a General-purpose programming language, general-purpose, High-level programming language, high-level, Comparison of multi-paradigm programming languages, multi-paradigm programming language which extends the ...
, the argument to ''f'' is expanded beforehand, yielding an infinite call sequence,
: .
This may be resolved by defining fix with an extra parameter.
let rec fix f x = f (fix f) x (* note the extra x; hence fix f = \x-> f (fix f) x *)
let factabs fact = function (* factabs has extra level of lambda abstraction *)
0 -> 1
, x -> x * fact (x-1)
let _ = (fix factabs) 5 (* evaluates to "120" *)
In a multi-paradigm functional language (one decorated with imperative features), such as Lisp
Lisp (historically LISP, an abbreviation of "list processing") is a family of programming languages with a long history and a distinctive, fully parenthesized Polish notation#Explanation, prefix notation.
Originally specified in the late 1950s, ...
, Peter Landin suggested the use of a variable assignment to create a fixed-point combinator, as in the below example using Scheme:
(define Y!
(lambda (f)
((lambda (g)
(set! g (f (lambda (x) (g x)))) ;; (set! g expr) assigns g the value of expr,
g) ;; replacing g's initial value of #f, creating
#f))) ;; thus the truly self-referential value in g
Using a lambda calculus with axioms for assignment statements, it can be shown that Y!
satisfies the same fixed-point law as the call-by-value Y combinator:
:
In more idiomatic modern Scheme usage, this would typically be handled via a letrec
expression, as lexical scope
In computer programming, the scope of a name binding (an association of a name to an entity, such as a variable) is the part of a program where the name binding is valid; that is, where the name can be used to refer to the entity. In other parts ...
was introduced to Lisp in the 1970s:
(define Y*
(lambda (f)
(letrec ;; (letrec ((g expr)) ...) locally defines g
((g ;; as expr recursively: g in expr refers to
(f (lambda (x) (g x))))) ;; that same g being defined, g = f (λx. g x)
g))) ;; ((Y* f) ...) = (g ...) = ((f (λx. g x)) ...)
Or without the internal label:
(define Y
(lambda (f)
((lambda (i) (i i))
(lambda (i)
(f (lambda (x)
(apply (i i) x)))))))
Imperative language implementation
This example is a slightly interpretive implementation of a fixed-point combinator. A class is used to contain the ''fix'' function, called ''fixer''. The function to be fixed is contained in a class that inherits from fixer. The ''fix'' function accesses the function to be fixed as a virtual function. As for the strict functional definition, ''fix'' is explicitly given an extra parameter ''x'', which means that lazy evaluation is not needed.
template
class fixer
;
class fact : public fixer
;
long result = fact().fix(5);
Another example can be shown to demonstrate SKI combinator calculus
The SKI combinator calculus is a combinatory logic system and a computational system. It can be thought of as a computer programming language, though it is not convenient for writing software. Instead, it is important in the mathematical theory o ...
(with given bird name from combinatory logic
Combinatory logic is a notation to eliminate the need for quantified variables in mathematical logic. It was introduced by Moses Schönfinkel and Haskell Curry, and has more recently been used in computer science as a theoretical model of com ...
) being used to build up Z combinator to achieve tail call
In computer science, a tail call is a subroutine call performed as the final action of a procedure. If the target of a tail is the same subroutine, the subroutine is said to be tail recursive, which is a special case of direct recursion. Tail recur ...
-like behavior through trampolining:
var K = a => b => a; // Kestrel
var S = a => b => c => a(c)(b(c)); // Starling
var I = S(K)(K); // Identity
var B = S(K(S))(K); // Bluebird
var C = S(B(B)(S))(K(K)); // Cardinal
var W = C(S)(I); // Warbler
var T = C(I); // Thrush
var V = B(C)(T); // Vireo
var I_ = C(C(I)); // Identity Bird Once Removed; same as C(B(B)(I))(I)
var C_ = B(C); // Cardinal Once Removed
var R_ = C_(C_); // Robin Once Removed
var V_ = B(R_)(C_); // Vireo Once Removed
var I__ = R_(V); // Identity Bird Twice Removed
var Z = B(W(I_))(V_(B)(W(I__)));
var Z2 = S(K(S(S(K(S(S(K)(K))(S(K)(K))))(S(K(S(K(S))(K)))(S(K(S(S(K)(K))))(K))))(K(S(S(K))))))(S(S(K(S(S(K(S(K(S))(K)))(S))(K(K))))(S(K(S(S(K(S(K(S))(K)))(S))(K(K))))(S(K(S))(K))))(K(S(S(K(S(S(K)(K))(S(K)(K))))(S(K(S(K(S))(K)))(S(K(S(S(K)(K))))(K))))(K(S(K(S(S(K(S(S(K(S(K(S))(K)))(S))(K(K))))(S(K(S(S(K(S(K(S))(K)))(S))(K(K))))(S(K(S(S(K)(K))))(K))))))(K))))));
// Alternative fully expanded form.
var Z3 = S(S(K(S(S)(K(S(S(K)(K))(S(K)(K))))))(K))(S(S(K(S))(K))(K(S(S(K(S))(S(K(S(K(S(K(S(K(S(S)(K(K))))(K)))(S)))(S(S(K)(K)))))(K)))(K(K(S(S(K)(K))(S(K)(K))))))));
// Another shorter version.
var trampoline = fn => ;
var count_fn = self => n =>
(console.log(n), n 0)
? n
: () => self(n - 1); // Return thunk "() => self(n - 1)" instead.
trampoline(Z(count_fn)(10));
trampoline(Z2(count_fn)(10));
trampoline(Z3(count_fn)(10));
Typing
In System F
System F (also polymorphic lambda calculus or second-order lambda calculus) is a typed lambda calculus that introduces, to simply typed lambda calculus, a mechanism of universal quantification over types. System F formalizes parametric polymorph ...
( polymorphic lambda calculus) a polymorphic fixed-point combinator has type
: ∀a.(a → a) → a
where is a type variable
In type theory and programming languages, a type variable is a mathematical variable ranging over types. Even in programming languages that allow mutable variables, a type variable remains an abstraction, in the sense that it does not correspond ...
. That is, if the type of fulfilling the equation is , – the most general type, – then the type of is . So then, takes a function which maps to and uses it to return a value of type .
In the simply typed lambda calculus extended with recursive data types, fixed-point operators can be written, but the type of a "useful" fixed-point operator (one whose application always returns) may be restricted.
In the simply typed lambda calculus
The simply typed lambda calculus (), a form
of type theory, is a typed interpretation of the lambda calculus with only one type constructor () that builds function types. It is the canonical and simplest example of a typed lambda calculus. The ...
, the fixed-point combinator Y cannot be assigned a type because at some point it would deal with the self-application sub-term by the application rule:
:
where has the infinite type . No fixed-point combinator can in fact be typed; in those systems, any support for recursion must be explicitly added to the language.
Type for the Y combinator
In programming languages that support recursive data types, the unbounded recursion in which creates the infinite type is broken by marking the type explicitly as a recursive type , which is defined so as to be isomorphic to (or just to be a synonym of) . The type value is created by simply tagging the function value of type with the data constructor tag (or any other of our choosing).
For example, in the following Haskell code, has Rec
and app
being the names of the two directions of the isomorphism, with types:
Rec :: (Rec a -> a) -> Rec a
app :: Rec a -> (Rec a -> a)
which lets us write:
newtype Rec a = Rec
y :: (a -> a) -> a
y f = (\ x -> f (app x x)) (Rec (\ x -> f (app x x)))
-- x :: Rec a
-- app x :: Rec a -> a
-- app x x :: a
Or equivalently in OCaml:
type 'a recc = In of ('a recc -> 'a)
let out (In x) = x
let y f = (fun x a -> f (out x x) a) (In (fun x a -> f (out x x) a))
Alternatively:
let y f = (fun x -> f (fun z -> out x x z)) (In (fun x -> f (fun z -> out x x z)))
General information
Because fixed-point combinators can be used to implement recursion, it is possible to use them to describe specific types of recursive computations, such as those in fixed-point iteration, iterative method
In computational mathematics, an iterative method is a Algorithm, mathematical procedure that uses an initial value to generate a sequence of improving approximate solutions for a class of problems, in which the ''i''-th approximation (called an " ...
s, recursive join in relational database
A relational database (RDB) is a database based on the relational model of data, as proposed by E. F. Codd in 1970.
A Relational Database Management System (RDBMS) is a type of database management system that stores data in a structured for ...
s, data-flow analysis
Data-flow analysis is a technique for gathering information about the possible set of values calculated at various points in a computer program. It forms the foundation for a wide variety of compiler optimizations and program verification techn ...
, FIRST and FOLLOW sets of non-terminals in a context-free grammar
In formal language theory, a context-free grammar (CFG) is a formal grammar whose production rules
can be applied to a nonterminal symbol regardless of its context.
In particular, in a context-free grammar, each production rule is of the fo ...
, transitive closure
In mathematics, the transitive closure of a homogeneous binary relation on a set (mathematics), set is the smallest Relation (mathematics), relation on that contains and is Transitive relation, transitive. For finite sets, "smallest" can be ...
, and other types of closure operations.
A function for which ''every'' input is a fixed point is called an identity function
Graph of the identity function on the real numbers
In mathematics, an identity function, also called an identity relation, identity map or identity transformation, is a function that always returns the value that was used as its argument, unc ...
. Formally:
:
In contrast to universal quantification
In mathematical logic, a universal quantification is a type of quantifier, a logical constant which is interpreted as "given any", "for all", "for every", or "given an arbitrary element". It expresses that a predicate can be satisfied by e ...
over all , a fixed-point combinator constructs ''one'' value that is a fixed point of . The remarkable property of a fixed-point combinator is that it constructs a fixed point for an ''arbitrary given'' function .
Other functions have the special property that, after being applied once, further applications don't have any effect. More formally:
:
Such functions are called idempotent
Idempotence (, ) is the property of certain operations in mathematics and computer science whereby they can be applied multiple times without changing the result beyond the initial application. The concept of idempotence arises in a number of pl ...
(see also Projection (mathematics)
In mathematics, a projection is an idempotent mapping of a set (or other mathematical structure) into a subset (or sub-structure). In this case, idempotent means that projecting twice is the same as projecting once. The restriction to a subspa ...
). An example of such a function is the function that returns ''0'' for all even integers, and ''1'' for all odd integers.
In lambda calculus
In mathematical logic, the lambda calculus (also written as ''λ''-calculus) is a formal system for expressing computability, computation based on function Abstraction (computer science), abstraction and function application, application using var ...
,from a computational point of view, applying a fixed-point combinator to an identity function or an idempotent function typically results in non-terminating computation. For example, obtaining
:
where the resulting term can only reduce to itself and represents an infinite loop.
Fixed-point combinators do not necessarily exist in more restrictive models of computation. For instance, they do not exist in simply typed lambda calculus
The simply typed lambda calculus (), a form
of type theory, is a typed interpretation of the lambda calculus with only one type constructor () that builds function types. It is the canonical and simplest example of a typed lambda calculus. The ...
.
The Y combinator allows recursion
Recursion occurs when the definition of a concept or process depends on a simpler or previous version of itself. Recursion is used in a variety of disciplines ranging from linguistics to logic. The most common application of recursion is in m ...
to be defined as a set of rewrite rule
In mathematics, computer science, and logic, rewriting covers a wide range of methods of replacing subterms of a well-formed formula, formula with other terms. Such methods may be achieved by rewriting systems (also known as rewrite systems, rewr ...
s, without requiring native recursion support in the language.
In programming languages that support anonymous function
In computer programming, an anonymous function (function literal, expression or block) is a function definition that is not bound to an identifier. Anonymous functions are often arguments being passed to higher-order functions or used for const ...
s, fixed-point combinators allow the definition and use of anonymous recursive functions, i.e., without having to bind
BIND () is a suite of software for interacting with the Domain Name System (DNS). Its most prominent component, named (pronounced ''name-dee'': , short for ''name Daemon (computing), daemon''), performs both of the main DNS server roles, acting ...
such functions to identifier
An identifier is a name that identifies (that is, labels the identity of) either a unique object or a unique ''class'' of objects, where the "object" or class may be an idea, person, physical countable object (or class thereof), or physical mass ...
s. In this setting, the use of fixed-point combinators is sometimes called ''anonymous recursion
In computer science, anonymous recursion is Recursion (computer science), recursion which does not explicitly call a function by name. This can be done either explicitly, by using a higher-order function – passing in a function as an argument and ...
''.[This terminology appears to be largely , but it appears in:
* Trey Nash, ''Accelerated C# 2008'', Apress, 2007, , p. 462—463. Derived substantially fro]
Wes Dyer
s blog (see next item).
* Wes Dye
Anonymous Recursion in C#
February 02, 2007, contains a substantially similar example found in the book above, but accompanied by more discussion.[The If Work]
Deriving the Y combinator
January 10, 2008
See also
* Anonymous function
In computer programming, an anonymous function (function literal, expression or block) is a function definition that is not bound to an identifier. Anonymous functions are often arguments being passed to higher-order functions or used for const ...
* Fixed-point iteration
* Lambda calculus#Recursion and fixed points
* Lambda lifting
Lambda lifting is a meta-process that restructures a computer program so that functions are defined independently of each other in a global scope. An individual ''lift'' transforms a local function (subroutine) into a global function. It is a tw ...
* Let expression
In computer science, a "let" expression associates a function definition with a restricted scope.
The "let" expression may also be defined in mathematics, where it associates a Boolean condition with a restricted scope.
The "let" expression may ...
Notes
References
* Werner Kluge, ''Abstract computing machines: a lambda calculus perspective'', Springer, 2005, , pp. 73–77
* Mayer Goldberg, (2005)
On the Recursive Enumerability of Fixed-Point Combinators
', BRICS Report RS-05-1, University of Aarhus
* Matthias Felleisen
Matthias Felleisen is a German-American computer science professor and author. He grew up in Germany and immigrated to the US in his twenties. He received his PhD from Indiana University Bloomington under the direction of Daniel P. Friedman.
...
A Lecture on the ''Why'' of ''Y''
External links
Manfred von Thun, (2002 or earlier)
The Lambda Calculus - notes by Don Blaheta, October 12, 2000
"A Use of the Y Combinator in Ruby"
Rosetta code - Y combinator
{{DEFAULTSORT:Fixed Point Combinator
Combinatory logic
Fixed points (mathematics)
Lambda calculus
Mathematics of computing
Recursion
Programming language comparisons
Articles with example C++ code
Articles with example Haskell code
Articles with example JavaScript code
Articles with example Lisp (programming language) code
Articles with example OCaml code