Fixed-point combinator
https://en.wikipedia.org/wiki/Fixed-point_combinator
Y := λf. (λx. f (x x)) (λx. f (x x))
In math, a fixed point of a function is a value that is mapped to itself by the function,
f(x) = x
. In general, f(x) = y so a fixed point is when x = y.Some functions have none, some have one, some have more fixed points, but the identity function is an extreme since any input is a fixed point,
id(x) = x
.An example of a function with a single fixed point is
sq(x) = x²
whose domain is ℕ; its only fixed point is at x = 1 such thatsq(1) = 1
.In combinatory logic, a fixpoint combinator, is a HOF called
fix
that finds a fixed point of the input argument function.In fact, H. Curry has shown that, in LC, every functions has a fixed point.
TOC
Y combinator
Fixed-point combinator
Values and domains
Function versus implementation
Combinators
Y in programming
factorial
Fixed-point combinators in LC
Equivalent definition of a fixed-point combinator
Derivation of the Y combinator
Other fixed-point combinators
Strict fixed-point combinator
Non-standard fixed-point combinators
Implementation in other languages
Lazy functional implementation
Strict functional implementation
Imperative language implementation
Typing
Type for the Y combinator
Y combinator
In the untyped lambda calculus, every function has a fixed point
Curry's paradoxical combinator Y :=
λf. (λx. f (x x)) (λx. f (x x))
In PL with 1st class fns, Y can be used to implement recursion if lacking
Y may be used in implementing Curry's paradox. The heart of Curry's paradox is that untyped LC is unsound as a deductive system, and the Y combinator demonstrates that by allowing an anonymous expression to represent zero, or even many values. This is inconsistent in mathematical logic.
Applied to a unary function, Y combinator diverges. To curb the execution and emulate loops, another (the second, or usually the last) parameter is used as the counter. Used this way, Y combinator implements simple recursion. Since, in LC, it's not possible to define a function in terms of itself, Y is used for recursion which is possible due to function self-application.
The starting point is the little omega function which is an example of self-application, but it diverges, forever reproducing itself,
ω := λf.ff
.The most general recursive function is
fix f = f (fix f)
, in term of which all recursive functions can be encoded.fix
returns the fixpoint of the supplied function; however, it doesn't really find any particular fixpoint, it more represents or "encodes" the solution - as the LHS expression itself. It's like, for any functionf
, its fixpoint isf (fix f)
, which when expanded producesf (f (fix f))
,f (f (f (fix f)))
, ...,f (f ...f (fix f)...))
. In FPL, this "forward expansion", when the fix function is implemented as a datatype, likeFix f = f (Fix f)
, can be considered as addition of layers (off
), while the "backward reduction" is like peeling off these layers.The key to curbing the recursion is to have at least a binary function whose second argument acts as the control counter, so it is checked before entering the body which "pulls the recursion further" by adding another recursive layer.
Last updated
Was this helpful?