fbpx
Wikipedia

Fixed-point combinator

In combinatory logic for computer science, a fixed-point combinator (or fixpoint combinator),[1]: p.26  is a higher-order function (i.e. a function which takes a function as argument) 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 and in functional programming languages and provide a means to allow for recursive definitions.

Y combinator in lambda calculus edit

In the classical untyped lambda calculus, every function has a fixed point. A particular implementation of   is Haskell Curry's paradoxical combinator Y, given by[2]: 131 [note 1]

 

(Here we use 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, is left-associative, and has higher precedence than the period.)

Verification edit

The following calculation verifies that   is indeed a fixed point of the function  :

    by the definition of  
  by β-reduction: replacing the formal argument f of Y with the actual argument g
  by β-reduction: replacing the formal argument x of the first function with the actual argument  
  by second equality, above

The lambda term   may not, in general, β-reduce to the term  . However, both terms β-reduce to the same term, as shown.

Uses edit

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 additional 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. The lambda calculus does not allow a function to appear as a term in its own definition as is possible in many programming languages, 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. 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 edit

An example implementation of the Y combinator in two languages is presented below.

# Y Combinator in Python  Y = lambda f: (lambda x: f(x(x)))(lambda x: f(x(x)))  Y(Y) 
// Y Combinator in C++, using C++ 14 extensions  int main() {  auto Y = [](auto f) {  auto f1 = [f](auto x) -> decltype(f) {  return f(x(x));  };  return f1(f1);  };   Y(Y); } 

Note that both of these programs, while formally correct, are useless in practice; they both loop indefinitely until they terminate through stack overflow. More generally, as both Python and C++ use strict evaluation, the Y combinator is generally useless in those languages; see below for the Z combinator, which can be used in strict programming languages.

Fixed-point combinator edit

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:

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 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 edit

Many functions do not have any fixed points, for instance   with  . Using Church encoding, 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 expression, 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. If trying to compute Y f in an actual programming language, an infinite loop will occur.

Function versus implementation edit

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.[3] 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" edit

Combinatory logic is a higher-order functions theory. A combinator is a closed lambda expression, meaning that it has no free variables. 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 edit

Fixed-point combinators can be used to implement recursive definition of functions. However, they are rarely used in practical programming.[4] Strongly normalizing type systems such as the simply typed lambda calculus 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.[1]: page 232 

The factorial function edit

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. If we want to implement this in lambda calculus, where integers are represented using Church encoding, we run into the problem that the lambda calculus does not allow 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 edit

The Y combinator, discovered by Haskell B. Curry, is defined as

 

Other fixed-point combinators edit

In untyped lambda calculus fixed-point combinators are not especially rare. In fact there are infinitely many of them.[5] In 2005 Mayer Goldberg showed that the set of fixed-point combinators of untyped lambda calculus is recursively enumerable.[6]

The Y combinator can be expressed in the SKI-calculus as

 

Additional combinators (B, C, K, W system) allow for a much shorter definition. With   the self-application combinator, since   and  , the above becomes

 

The simplest fixed-point combinator in the SK-calculus, 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):[7][2]: 132 

 

Its advantage over   is that   beta-reduces to  ,[note 2] 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,[8][9][10] which may be denoted Y*.

Strict fixed-point combinator edit

In a strict programming language the Y combinator will expand until stack overflow, or never halt in case of tail call optimization.[11] 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:[12]

 

and in lambda calculus it is an eta-expansion of the Y combinator:

 

Non-standard fixed-point combinators edit

If F is a fixed-point combinator in untyped lambda calculus, then we have

 

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

 
 

The set of non-standard fixed-point combinators is not recursively enumerable.[6]

Implementation in other languages edit

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 paradigms are given below.

Lazy functional implementation edit

In a language that supports lazy evaluation, like in Haskell, 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 datatypes, 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: [13]

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,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 edit

In a strict functional language, as illustrated below with OCaml, 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; here 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, Landin (1963)[full citation needed] suggests the use of a variable assignment to create a fixed-point combinator, as in the below example using Scheme:

(define Y!  (lambda (f)  ((lambda (i)   (set! i (f (lambda (x) (i x)))) ;; (set! i expr) assigns i the value of expr  i) ;; replacing it in the present lexical scope  #f))) 

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:[14][15]

 

In more idiomatic modern Lisp usage, this would typically be handled via a lexically scoped label (a let expression), as lexical scope was not introduced to Lisp until the 1970s:

(define Y*  (lambda (f)  ((lambda (i)  (let ((i (f (lambda (x) (i x))))) ;; (let ((i expr)) i) locally defines i as expr  i)) ;; non-recursively: thus i in expr is not expr  #f))) 

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 edit

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 <typename R, typename D> class fixer { public:  R fix(D x)  {  return f(x);  } private:  virtual R f(D) = 0; }; class fact : public fixer<long, long> {  virtual long f(long x)  {  if (x == 0)  {  return 1;  }  return x * fix(x-1);  } }; long result = fact().fix(5); 

Typing edit

In System F (polymorphic lambda calculus) a polymorphic fixed-point combinator has type[citation needed];

∀a.(a → a) → a

where a is a type variable. That is, fix takes a function, which maps a → a and uses it to return a value of type a.

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 fixed-point combinator Y cannot be assigned a type[16] 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 edit

In programming languages that support recursive data types, it is possible to type the Y combinator by appropriately accounting for the recursion at the type level. The need to self-apply the variable x can be managed using a type (Rec a), which is defined so as to be isomorphic to (Rec a -> a).

For example, in the following Haskell code, we have In and out being the names of the two directions of the isomorphism, with types:[17][18]

In :: (Rec a -> a) -> Rec a out :: Rec a -> (Rec a -> a) 

which lets us write:

newtype Rec a = In { out :: Rec a -> a } y :: (a -> a) -> a y = \f -> (\x -> f (out x x)) (In (\x -> f (out x x))) 

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 edit

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 methods, recursive join in relational databases, data-flow analysis, FIRST and FOLLOW sets of non-terminals in a context-free grammar, transitive closure, and other types of closure operations.

A function for which every input is a fixed point is called an identity function. Formally:

 

In contrast to universal quantification 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 (see also Projection (mathematics)). 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, 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, we obtain

 

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 Y combinator allows recursion to be defined as a set of rewrite rules,[19] without requiring native recursion support in the language.[20]

In programming languages that support anonymous functions, fixed-point combinators allow the definition and use of anonymous recursive functions, i.e. without having to bind such functions to identifiers. In this setting, the use of fixed-point combinators is sometimes called anonymous recursion.[note 3][21]

See also edit

Notes edit

  1. ^ Throughout this article, the syntax rules given in Lambda calculus#Notation are used, to save parentheses.
  2. ^                  
  3. ^ This terminology appears to be largely folklore, but it does appear in the following:
    • Trey Nash, Accelerated C# 2008, Apress, 2007, ISBN 1-59059-873-3, p. 462—463. Derived substantially from Wes Dyer's blog (see next item).
    • Wes Dyer Anonymous Recursion in C#, February 02, 2007, contains a substantially similar example found in the book above, but accompanied by more discussion.

References edit

  1. ^ a b Peyton Jones, Simon L. (1987). The Implementation of Functional Programming (PDF). Prentice Hall International.
  2. ^ a b Henk Barendregt (1985). The Lambda Calculus – Its Syntax and Semantics. Studies in Logic and the Foundations of Mathematics. Vol. 103. Amsterdam: North-Holland. ISBN 0444867481.
  3. ^ Selinger, Peter. "Lecture Notes on Lambda Calculus (PDF)". p. 6.
  4. ^ "For those of us who don't know what a Y-Combinator is or why it's useful, ..." Hacker News. Retrieved 2 August 2020.
  5. ^ Bimbó, Katalin (27 July 2011). Combinatory Logic: Pure, Applied and Typed. CRC Press. p. 48. ISBN 9781439800010.
  6. ^ a b Goldberg, 2005
  7. ^ Alan Mathison Turing (December 1937). "The  -function in  - -conversion". Journal of Symbolic Logic. 2 (4): 164. JSTOR 2268281.
  8. ^ "Many faces of the fixed-point combinator". okmij.org.
  9. ^ Polyvariadic Y in pure Haskell98 2016-03-04 at the Wayback Machine, lang.haskell.cafe, October 28, 2003
  10. ^ "recursion - Fixed-point combinator for mutually recursive functions?". Stack Overflow.
  11. ^ Bene, Adam (17 August 2017). "Fixed-Point Combinators in JavaScript". Bene Studio. Medium. Retrieved 2 August 2020.
  12. ^ "CS 6110 S17 Lecture 5. Recursion and Fixed-Point Combinators" (PDF). Cornell University. 4.1 A CBV Fixed-Point Combinator.
  13. ^ The original definition in Data.Function.
  14. ^ Felleisen, Matthias (1987). The Lambda-v-CS Calculus. Indiana University.
  15. ^ Talcott, Carolyn (1985). The Essence of Rum: A theory of the intensional and extensional aspects of Lisp-type computation (Ph.D. thesis). Stanford University.
  16. ^ An Introduction to the Lambda Calculus 2014-04-08 at the Wayback Machine
  17. ^ Haskell mailing list thread on How to define Y combinator in Haskell, 15 Sep 2006
  18. ^ Geuvers, Herman; Verkoelen, Joep. On Fixed point and Looping Combinators in Type Theory. CiteSeerX 10.1.1.158.1478.
  19. ^ Daniel P. Friedman, Matthias Felleisen (1986). "Chapter 9 - Lambda The Ultimate". The Little Lisper. Science Research Associates. p. 179. "In the chapter we have derived a Y-combinator which allows us to write recursive functions of one argument without using define."
  20. ^ Mike Vanier. "The Y Combinator (Slight Return) or: How to Succeed at Recursion Without Really Recursing". from the original on 2011-08-22. "More generally, Y gives us a way to get recursion in a programming language that supports first-class functions but that doesn't have recursion built in to it."
  21. ^ The If Works Deriving the Y combinator, January 10th, 2008
  • Werner Kluge, Abstract computing machines: a lambda calculus perspective, Springer, 2005, ISBN 3-540-21146-2, pp. 73–77
  • Mayer Goldberg, (2005) On the Recursive Enumerability of Fixed-Point Combinators, BRICS Report RS-05-1, University of Aarhus
  • Matthias Felleisen, A Lecture on the Why of Y.

External links edit

  • Recursion Theory and Joy, Manfred von Thun, (2002 or earlier)
  • The Lambda Calculus - notes by Don Blaheta, October 12, 2000
  • Y Combinator 2009-03-23 at the Wayback Machine
  • "A Use of the Y Combinator in Ruby"
  • "Functional programming in Ada"
  • Rosetta code - Y combinator

fixed, point, combinator, combinatory, logic, computer, science, fixed, point, combinator, fixpoint, combinator, higher, order, function, function, which, takes, function, argument, that, returns, some, fixed, point, value, that, mapped, itself, argument, func. In combinatory logic for computer science a fixed point combinator or fixpoint combinator 1 p 26 is a higher order function i e a function which takes a function as argument that returns some fixed point a value that is mapped to itself of its argument function if one exists Formally if fix displaystyle textrm fix is a fixed point combinator and the function f displaystyle f has one or more fixed points then fix f displaystyle textrm fix f is one of these fixed points i e f fix f fix f displaystyle f textrm fix f textrm fix f Fixed point combinators can be defined in the lambda calculus and in functional programming languages and provide a means to allow for recursive definitions Contents 1 Y combinator in lambda calculus 1 1 Verification 1 2 Uses 1 3 Example implementations 2 Fixed point combinator 2 1 Values and domains 2 2 Function versus implementation 2 3 Definition of the term combinator 3 Recursive definitions and fixed point combinators 3 1 The factorial function 4 Fixed point combinators in lambda calculus 4 1 Other fixed point combinators 4 2 Strict fixed point combinator 4 3 Non standard fixed point combinators 5 Implementation in other languages 5 1 Lazy functional implementation 5 2 Strict functional implementation 5 3 Imperative language implementation 6 Typing 6 1 Type for the Y combinator 7 General information 8 See also 9 Notes 10 References 11 External linksY combinator in lambda calculus editIn the classical untyped lambda calculus every function has a fixed point A particular implementation of fix displaystyle textrm fix nbsp is Haskell Curry s paradoxical combinator Y given by 2 131 note 1 Y l f l x f x x l x f x x displaystyle Y lambda f lambda x f x x lambda x f x x nbsp Here we use 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 l x f x x displaystyle lambda x f x x nbsp denotes a function that takes one argument x thought of as a function and returns the expression f x x displaystyle f x x nbsp where x x displaystyle x x nbsp denotes x applied to itself Juxtaposition of expressions denotes function application is left associative and has higher precedence than the period Verification edit The following calculation verifies that Y g displaystyle Yg nbsp is indeed a fixed point of the function g displaystyle g nbsp Y g displaystyle Y g nbsp l f l x f x x l x f x x g displaystyle lambda f lambda x f x x lambda x f x x g nbsp by the definition of Y displaystyle Y nbsp l x g x x l x g x x displaystyle lambda x g x x lambda x g x x nbsp by b reduction replacing the formal argument f of Y with the actual argument g g l x g x x l x g x x displaystyle g lambda x g x x lambda x g x x nbsp by b reduction replacing the formal argument x of the first function with the actual argument l x g x x displaystyle lambda x g x x nbsp g Y g displaystyle g Y g nbsp by second equality above The lambda term g Y g displaystyle g Y g nbsp may not in general b reduce to the term Y g displaystyle Y g nbsp However both terms b reduce to the same term as shown Uses edit 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 additional 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 The lambda calculus does not allow a function to appear as a term in its own definition as is possible in many programming languages 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 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 edit An example implementation of the Y combinator in two languages is presented below Y Combinator in Python Y lambda f lambda x f x x lambda x f x x Y Y Y Combinator in C using C 14 extensions int main auto Y auto f auto f1 f auto x gt decltype f return f x x return f1 f1 Y Y Note that both of these programs while formally correct are useless in practice they both loop indefinitely until they terminate through stack overflow More generally as both Python and C use strict evaluation the Y combinator is generally useless in those languages see below for the Z combinator which can be used in strict programming languages Fixed point combinator editThe 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 Untyped lambda calculus Typed lambda calculus Functional programming Imperative programming 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 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 edit Many functions do not have any fixed points for instance f N N displaystyle f mathbb N to mathbb N nbsp with f n n 1 displaystyle f n n 1 nbsp Using Church encoding 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 expression 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 If trying to compute Y f in an actual programming language an infinite loop will occur Function versus implementation edit 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 3 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 edit Combinatory logic is a higher order functions theory A combinator is a closed lambda expression meaning that it has no free variables 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 editFixed point combinators can be used to implement recursive definition of functions However they are rarely used in practical programming 4 Strongly normalizing type systems such as the simply typed lambda calculus 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 1 page 232 The factorial function edit 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 fact n 1 if n 0 n fact n 1 otherwise displaystyle operatorname fact n begin cases 1 amp text if n 0 n times operatorname fact n 1 amp text otherwise end cases nbsp where n is a non negative integer If we want to implement this in lambda calculus where integers are represented using Church encoding we run into the problem that the lambda calculus does not allow the name of a function fact to be used in the function s definition This can be circumvented using a fixed point combinator fix displaystyle textsf fix nbsp as follows Define a function F of two arguments f and n F f n IsZero n 1 multiply n f pred n displaystyle F f n operatorname IsZero n 1 operatorname multiply n f operatorname pred n nbsp Here IsZero n displaystyle operatorname IsZero n nbsp is a function that takes two arguments and returns its first argument if n 0 and its second argument otherwise pred n displaystyle operatorname pred n nbsp evaluates to n 1 Now define fact fix F displaystyle operatorname fact textsf fix F nbsp Then fact displaystyle operatorname fact nbsp is a fixed point of F which gives fact n F fact n IsZero n 1 multiply n fact pred n displaystyle begin aligned operatorname fact n amp F operatorname fact n amp operatorname IsZero n 1 operatorname multiply n operatorname fact operatorname pred n end aligned nbsp as desired Fixed point combinators in lambda calculus editThe Y combinator discovered by Haskell B Curry is defined as Y l f l x f x x l x f x x displaystyle Y lambda f lambda x f x x lambda x f x x nbsp Other fixed point combinators edit In untyped lambda calculus fixed point combinators are not especially rare In fact there are infinitely many of them 5 In 2005 Mayer Goldberg showed that the set of fixed point combinators of untyped lambda calculus is recursively enumerable 6 The Y combinator can be expressed in the SKI calculus as Y S K S I I S S K S K K S I I displaystyle Y S K SII S S KS K K SII nbsp Additional combinators B C K W system allow for a much shorter definition With U S I I displaystyle U SII nbsp the self application combinator since S K x y z x y z B x y z displaystyle S Kx yz x yz Bxyz nbsp and S x K y z x z y C x y z displaystyle Sx Ky z xzy Cxyz nbsp the above becomes Y S K U S B K U B U C B U displaystyle Y S KU SB KU BU CBU nbsp The simplest fixed point combinator in the SK calculus found by John Tromp is Y S S K S K S S S S S K K displaystyle Y SSK S K SS S SSK K nbsp although note that it is not in normal form which is longer This combinator corresponds to the lambda expression Y l x y x y x l y x y x y x displaystyle Y lambda xy xyx lambda yx y xyx nbsp The following fixed point combinator is simpler than the Y combinator and b reduces into the Y combinator it is sometimes cited as the Y combinator itself X l f l x x x l x f x x displaystyle X lambda f lambda x xx lambda x f xx nbsp Another common fixed point combinator is the Turing fixed point combinator named after its discoverer Alan Turing 7 2 132 8 l x y y x x y l x y y x x y displaystyle Theta lambda xy y xxy lambda xy y xxy nbsp Its advantage over Y displaystyle Y nbsp is that 8 f displaystyle Theta f nbsp beta reduces to f 8 f displaystyle f Theta f nbsp note 2 whereas Y f displaystyle Y f nbsp and f Y f displaystyle f Yf nbsp only beta reduce to a common term 8 displaystyle Theta nbsp also has a simple call by value form 8 v l x y y l z x x y z l x y y l z x x y z displaystyle Theta v lambda xy y lambda z xxyz lambda xy y lambda z xxyz nbsp The analog for mutual recursion is a polyvariadic fix point combinator 8 9 10 which may be denoted Y Strict fixed point combinator edit In a strict programming language the Y combinator will expand until stack overflow or never halt in case of tail call optimization 11 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 Z g displaystyle Zg nbsp in the right hand side of the definition 12 Z g v g Z g v displaystyle Zgv g Zg v nbsp and in lambda calculus it is an eta expansion of the Y combinator Z l f l x f l v x x v l x f l v x x v displaystyle Z lambda f lambda x f lambda v xxv lambda x f lambda v xxv nbsp Non standard fixed point combinators edit If F is a fixed point combinator in untyped lambda calculus then we haveF l x F x l x x F x l x x x F x displaystyle F lambda x Fx lambda x x Fx lambda x x x Fx cdots nbsp Terms that have the same Bohm tree as a fixed point combinator i e have the same infinite extension l x x x x displaystyle lambda x x x x cdots nbsp 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 N B M B B M B displaystyle N BM B BM B nbsp where B l x y z x y z displaystyle B lambda xyz x yz nbsp M l x x x displaystyle M lambda x xx nbsp The set of non standard fixed point combinators is not recursively enumerable 6 Implementation in other languages editThe 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 paradigms are given below Lazy functional implementation edit In a language that supports lazy evaluation like in Haskell 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 datatypes 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 13 fix fix a gt a gt 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 gt 9 this evaluates to 9 fix x gt 3 x evaluates to the lazy infinite list 3 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 edit In a strict functional language as illustrated below with OCaml the argument to f is expanded beforehand yielding an infinite call sequence f f f f i x f x displaystyle f f f mathsf fix f x nbsp This may be resolved by defining fix with an extra parameter let rec fix f x f fix f x note the extra x here fix f x gt f fix f x let factabs fact function factabs has extra level of lambda abstraction 0 gt 1 x gt 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 Landin 1963 full citation needed suggests the use of a variable assignment to create a fixed point combinator as in the below example using Scheme define Y lambda f lambda i set i f lambda x i x set i expr assigns i the value of expr i replacing it in the present lexical scope f 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 14 15 Y l x e e l x e Y l x e e displaystyle Y lambda x e e lambda x e Y lambda x e e nbsp In more idiomatic modern Lisp usage this would typically be handled via a lexically scoped label a let expression as lexical scope was not introduced to Lisp until the 1970s define Y lambda f lambda i let i f lambda x i x let i expr i locally defines i as expr i non recursively thus i in expr is not expr f 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 edit 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 lt typename R typename D gt class fixer public R fix D x return f x private virtual R f D 0 class fact public fixer lt long long gt virtual long f long x if x 0 return 1 return x fix x 1 long result fact fix 5 Typing editIn System F polymorphic lambda calculus a polymorphic fixed point combinator has type citation needed a a a a where a is a type variable That is fix takes a function which maps a a and uses it to return a value of type a 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 fixed point combinator Y cannot be assigned a type 16 because at some point it would deal with the self application sub term x x displaystyle x x nbsp by the application rule G x t 1 t 2 G x t 1 G x x t 2 displaystyle Gamma vdash x t 1 to t 2 quad Gamma vdash x t 1 over Gamma vdash x x t 2 nbsp where x displaystyle x nbsp has the infinite type t 1 t 1 t 2 displaystyle t 1 t 1 to t 2 nbsp 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 edit In programming languages that support recursive data types it is possible to type the Y combinator by appropriately accounting for the recursion at the type level The need to self apply the variable x can be managed using a type Rec a which is defined so as to be isomorphic to Rec a gt a For example in the following Haskell code we have In and out being the names of the two directions of the isomorphism with types 17 18 In Rec a gt a gt Rec a out Rec a gt Rec a gt a which lets us write newtype Rec a In out Rec a gt a y a gt a gt a y f gt x gt f out x x In x gt f out x x Or equivalently in OCaml type a recc In of a recc gt a let out In x x let y f fun x a gt f out x x a In fun x a gt f out x x a Alternatively let y f fun x gt f fun z gt out x x z In fun x gt f fun z gt out x x z General information editBecause 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 methods recursive join in relational databases data flow analysis FIRST and FOLLOW sets of non terminals in a context free grammar transitive closure and other types of closure operations A function for which every input is a fixed point is called an identity function Formally x f x x displaystyle forall x f x x nbsp In contrast to universal quantification over all x displaystyle x nbsp a fixed point combinator constructs one value that is a fixed point of f displaystyle f nbsp The remarkable property of a fixed point combinator is that it constructs a fixed point for an arbitrary given function f displaystyle f nbsp Other functions have the special property that after being applied once further applications don t have any effect More formally x f f x f x displaystyle forall x f f x f x nbsp Such functions are called idempotent see also Projection mathematics 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 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 we obtain Y l x x l x x x l x x x displaystyle Y lambda x x lambda x xx lambda x xx nbsp 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 Y combinator allows recursion to be defined as a set of rewrite rules 19 without requiring native recursion support in the language 20 In programming languages that support anonymous functions fixed point combinators allow the definition and use of anonymous recursive functions i e without having to bind such functions to identifiers In this setting the use of fixed point combinators is sometimes called anonymous recursion note 3 21 See also editAnonymous function Fixed point iteration Lambda calculus Recursion and fixed points Lambda lifting Let expressionNotes edit Throughout this article the syntax rules given in Lambda calculus Notation are used to save parentheses 8 f displaystyle Theta f nbsp displaystyle equiv nbsp l x y y x x y l x y y x x y f displaystyle lambda xy y xxy lambda xy y xxy f nbsp displaystyle to nbsp l y y l x y y x x y l x y y x x y y f displaystyle lambda y y lambda xy y xxy lambda xy y xxy y f nbsp displaystyle to nbsp f l x y y x x y l x y y x x y f displaystyle f lambda xy y xxy lambda xy y xxy f nbsp displaystyle equiv nbsp f 8 f displaystyle f Theta f nbsp This terminology appears to be largely folklore but it does appear in the following Trey Nash Accelerated C 2008 Apress 2007 ISBN 1 59059 873 3 p 462 463 Derived substantially from Wes Dyer s blog see next item Wes Dyer Anonymous Recursion in C February 02 2007 contains a substantially similar example found in the book above but accompanied by more discussion References edit a b Peyton Jones Simon L 1987 The Implementation of Functional Programming PDF Prentice Hall International a b Henk Barendregt 1985 The Lambda Calculus Its Syntax and Semantics Studies in Logic and the Foundations of Mathematics Vol 103 Amsterdam North Holland ISBN 0444867481 Selinger Peter Lecture Notes on Lambda Calculus PDF p 6 For those of us who don t know what a Y Combinator is or why it s useful Hacker News Retrieved 2 August 2020 Bimbo Katalin 27 July 2011 Combinatory Logic Pure Applied and Typed CRC Press p 48 ISBN 9781439800010 a b Goldberg 2005 Alan Mathison Turing December 1937 The p displaystyle p nbsp function in l displaystyle lambda nbsp K displaystyle K nbsp conversion Journal of Symbolic Logic 2 4 164 JSTOR 2268281 Many faces of the fixed point combinator okmij org Polyvariadic Y in pure Haskell98 Archived 2016 03 04 at the Wayback Machine lang haskell cafe October 28 2003 recursion Fixed point combinator for mutually recursive functions Stack Overflow Bene Adam 17 August 2017 Fixed Point Combinators in JavaScript Bene Studio Medium Retrieved 2 August 2020 CS 6110 S17 Lecture 5 Recursion and Fixed Point Combinators PDF Cornell University 4 1 A CBV Fixed Point Combinator The original definition in Data Function Felleisen Matthias 1987 The Lambda v CS Calculus Indiana University Talcott Carolyn 1985 The Essence of Rum A theory of the intensional and extensional aspects of Lisp type computation Ph D thesis Stanford University An Introduction to the Lambda Calculus Archived 2014 04 08 at the Wayback Machine Haskell mailing list thread on How to define Y combinator in Haskell 15 Sep 2006 Geuvers Herman Verkoelen Joep On Fixed point and Looping Combinators in Type Theory CiteSeerX 10 1 1 158 1478 Daniel P Friedman Matthias Felleisen 1986 Chapter 9 Lambda The Ultimate The Little Lisper Science Research Associates p 179 In the chapter we have derived a Y combinator which allows us to write recursive functions of one argument without using define Mike Vanier The Y Combinator Slight Return or How to Succeed at Recursion Without Really Recursing Archived from the original on 2011 08 22 More generally Y gives us a way to get recursion in a programming language that supports first class functions but that doesn t have recursion built in to it The If Works Deriving the Y combinator January 10th 2008 Werner Kluge Abstract computing machines a lambda calculus perspective Springer 2005 ISBN 3 540 21146 2 pp 73 77 Mayer Goldberg 2005 On the Recursive Enumerability of Fixed Point Combinators BRICS Report RS 05 1 University of Aarhus Matthias Felleisen A Lecture on the Why of Y External links edit nbsp Wikibooks has a book on the topic of Haskell Fix and recursion Recursion Theory and Joy Manfred von Thun 2002 or earlier The Lambda Calculus notes by Don Blaheta October 12 2000 Y Combinator Archived 2009 03 23 at the Wayback Machine A Use of the Y Combinator in Ruby Functional programming in Ada Rosetta code Y combinator Retrieved from https en wikipedia org w index php title Fixed point combinator amp oldid 1220438428 Y combinator, wikipedia, wiki, book, books, library,

article

, read, download, free, free download, mp3, video, mp4, 3gp, jpg, jpeg, gif, png, picture, music, song, movie, book, game, games.