|
|
Line 1: |
Line 1: |
| {{Hatnote|[[Y combinator (disambiguation)|Y combinator]] links here. For the startup seed-funding company, see [[Y Combinator (company)]].}}
| | So, to avoid or do away with the retention issues, drink more water. Yes, it is very paradoxical, however true. But drinking more water can make the body realize that there is no scarcity of water. This might force it to flush out the water within the body, and also the toxins. Your body can stop keeping a lot of water. Having a lot of oranges plus alternative vitamin C-rich foods will enable the body do away with the retention quicker. Excessive salt inside the diet has a tendency to leave a person feeling bloated. This really is because, salt is a cause of water retention because well. Reduce the intake of salt inside your diet to the bare minimum, to keep water retention at bay. There are many detox diet plans that revolve about this principle.<br><br>No side impact of this miracle fat burner has been reported thus far. However, ensure that you buy a genuine supplement which contains all 8 ingredients reported above.<br><br>Dr. Sarah G. Khan warns which the compound in raspberry ketone supplements is usually synthetic and not really from raspberries. She equally points out which there were limited research into raspberry ketone plus negative effects include thyroid trouble, agitation and trouble sleeping.<br><br>For my diet - I stuck with a vegan diet that consisted of cabbage soup, kale chips, kosher dill pickles, and tofu. I used no butter or margarine plus relied heavily on olive oil, kosher salt, plus pepper. Instead of getting 3 huge food, I would have 8 food.<br><br>Dr. Oz views [http://safedietplansforwomen.com/raspberry-ketones raspberry ketone] as his "number one weight loss miracle in a bottle," he declared on his show recently. This compound, which is made from red raspberries, helps to control adiponectin, which is a hormone that stimulates your body to boost your metabolism. Some say it also suppresses their appetite. The result: your body burns fat more effectively and faster. Think you can just substitute red raspberries?<br><br>Garcinia cambogia (hydroxycitric acid or HCA) This really is tamarind, chosen in Indian foods. It's an appetite suppressant. I buy raspberry ketone diet it for $1 per bottle at Dollar Tree. This range equally contains cider vinegar. I take thee tablets daily with food.<br><br>Not several fat burners contain so many natural elements. Though you will find weight reduction diet medications which contain one or 2 of above revealed components, they usually function on 1 aspect of the health. A perfect blend of all of these ingredients is required for quick fat reduction without any side effects.<br><br>Some folks report headaches taking the Hydroxycut Caffeine Free, yet I did not experience any bad negative effects additional than periodic sleepiness. If you do experience any negative effects, decrease dosage or stop taking and talk to your doctor. |
| | |
| In [[computer science]], a '''fixed-point combinator''' (or '''fixpoint combinator<ref>{{cite book|last=Peyton Jones|first=Simon L.|title=The Implementation of Functional Programming|year=1987|publisher=Prentice Hall International|url=http://research.microsoft.com/en-us/um/people/simonpj/papers/slpj-book-1987/}}</ref>''') is a [[higher-order function]] ''y'' that satisfies the equation,
| |
| | |
| : <math> y\ f = f\ (y\ f) </math>
| |
| | |
| It is so named because, by setting <math> x = y\ f </math> it represents a solution to the [[fixed point (mathematics)|fixed point]] equation,
| |
| | |
| : <math> x = f\ x </math>
| |
| | |
| A ''fixed point'' of a function ''f'' is a value that doesn't change under the application of the function ''f''. Consider the function <math> f\ x = x^2</math>. 0 and 1 are fixed points of this function, because <math>0 = 0^2</math> and <math>1 = 1^2</math>. This function has no other fixed points.
| |
| | |
| A fixed point combinator need not exist for all functions. Also if ''f'' is a function of more than 1 parameter, the fixed point of the function need not be a [[Total_function#Total_function|total function]].
| |
| | |
| Functions that satisfy the equation for ''y'' expand as,
| |
| | |
| : <math> y\ f = f\ (\ldots f\ (y\ f) \ldots) </math>
| |
| | |
| A particular implementation of ''y'' is [[Haskell Curry|Curry's]] paradoxical combinator ''Y'', represented in [[Lambda calculus]] by,
| |
| | |
| : <math>\lambda f.(\lambda x.f\ (x\ x))\ (\lambda x.f\ (x\ x)) </math>
| |
| | |
| This combinator may be used in implementing [[Curry's paradox]]. The heart of Curry's paradox is that Lambda calculus 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 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 second variable 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. In the Lambda calculus it is not possible to refer to the definition of a function in a function body. Recursion may only be achieved by passing in a function as a parameter. The ''Y'' combinator demonstrates this style of programming.
| |
| | |
| ==Introduction==
| |
| | |
| The ''Y'' combinator is an implementation of the 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 because of the limitations of lambda calculus.
| |
| | |
| The fixed combinator may be used in a number of different areas,
| |
| | |
| * [[mathematics|General mathematics]]
| |
| * [[Lambda calculus|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. Even with lazy evaluation when the function to be fixed refers to its parameter, another call to the function is invoked. The calculation never gets started. The extra parameter is needed 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 fix 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 lambda calculus 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===
| |
| | |
| Every expression has one value. This is true in general mathematics and it must be true in lambda calculus. This means that in lambda calculus, applying a fixed point combinator to a function gives you an expression whose value is the fixed point of the function.
| |
| | |
| However this is a value in the lambda calculus domain, it may not correspond to any value in the domain of the function, so in a practical sense it is not necessarily a fixed point of the function, and only in the lambda calculus domain is it a fixed point of the equation.
| |
| | |
| For example, consider,
| |
| : <math> x^2 = -1 \implies x = \frac{-1}{x} \implies f\ x = \frac{-1}{x} \and Y\ f = x</math>
| |
| | |
| Assume that ''f'' may be represented by a lambda term. This equation has no solution in the real numbers. But in the domain of the [[Complex number|complex numbers]] ''i'' and ''-i'' are solutions. This demonstrates that there may be solutions to an equation in another domain. However the lambda term for the solution for the above equation is weirder than that. The lambda term <math>Y\ f</math> represents the state where x could be either ''i'' or ''-i'', as one value. The information distinguishing these two values has been lost, in the change of domain.
| |
| | |
| For the lambda calculus mathematician, this is a consequence of the definition of lambda calculus. For the programmer, it means that the beta reduction of the lambda term will loop forever, never reaching a normal form.
| |
| | |
| ===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 [[Intrinsic and extrinsic properties|extrinsic]] properties. That is, two functions are equal if they perform the same mapping. Lambda calculus and programming languages regard function identity as an intrinsic property. A functions 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 combinator (implementations) that satisfy the mathematical definition of a fixed-point combinator.
| |
| | |
| ===What is a "combinator"===
| |
| | |
| A [[Combinatory logic|combinator]] is a particular type of function that may be used in defining functions without using variables. The combinators may be combined to direct values to their correct places in the expression without ever naming them as variables.
| |
| | |
| ==Usage==
| |
| | |
| Usually when applied to functions of one parameter, implementations of the fixed point combinator fail to terminate. Functions with extra parameters are more interesting.
| |
| | |
| The Y combinator is an example of what makes the Lambda calculus inconsistent. So it should be regarded with suspicion. However it is safe to consider the Y combinator when defined in mathematic logic only. The definition is,
| |
| | |
| : <math> y\ f = f\ (y\ f) </math>
| |
| | |
| It is easy to see how ''f'' may be applied to one variable. Applying it to two or more variables requires adding them to the equation,
| |
| | |
| : <math> y\ f\ x = f\ (y\ f)\ x </math>
| |
| | |
| This version of the equation must be shown consistent with the previous by the definition for equality of functions,
| |
| | |
| : <math> (\forall x f\ x = g\ x) \equiv f = g </math>
| |
| | |
| This definition allows the two equations for y to be regarded as equivalent, provided that the domain of ''x'' is well defined. So if ''f'' has multiple parameters the ''y f'' may still be regarded as a fixed point, with some restrictions.
| |
| | |
| ===The factorial function===
| |
| | |
| The factorial function provides a good example of how the fixed point combinator may be applied to functions of two variables. The result demonstrates simple recursion, as would be implemented in a single loop, in an imperative language. The definition of numbers used is explained in [[Church encoding]]. The fixed point function is,
| |
| | |
| : <math> F\ f\ n = (\operatorname{IsZero}\ n)\ 1\ (\operatorname{multiply}\ n\ (f\ (\operatorname{pred}\ n))) </math>
| |
| | |
| so ''y F'' is,
| |
| | |
| : <math> y\ F\ n = F\ (y\ F)\ n </math>
| |
| or
| |
| : <math> y\ F\ n = (\operatorname{IsZero}\ n)\ 1\ (\operatorname{multiply}\ n\ ((y\ F)\ (\operatorname{pred}\ n))) </math>
| |
| | |
| Setting <math> y\ F = \operatorname{fact} </math> gives,
| |
| | |
| : <math> \operatorname{fact}\ n = (\operatorname{IsZero}\ n)\ 1\ (\operatorname{multiply}\ n\ (\operatorname{fact}\ (\operatorname{pred}\ n))) </math>
| |
| | |
| this definition is equivalent to the mathematical definition of factorial, | |
| | |
| : <math> \operatorname{fact}\ n = \operatorname{if} n = 0 \operatorname{then} 1 \operatorname{else} n * \operatorname{fact}\ (n - 1) </math>
| |
| | |
| This definition puts ''F'' in the role of the body of a loop to be iterated.
| |
| | |
| ==Fixed point combinators in lambda calculus==
| |
| | |
| The ''Y'' combinator, discovered by [[Haskell Curry|Haskell B. Curry]], is defined as:
| |
| | |
| : <math>Y = \lambda f.(\lambda x.f\ (x\ x))\ (\lambda x.f\ (x\ x))</math>
| |
| | |
| Beta reduction of this gives,
| |
| | |
| {| cellpadding="0"
| |
| | <math>Y\ g</math>
| |
| | <math>= (\lambda f.(\lambda x.f\ (x\ x))\ (\lambda x.f\ (x\ x)))\ g</math>
| |
| |style="padding-left:30px;"| (by definition of ''Y'')
| |
| |-
| |
| |
| |
| | <math>= (\lambda x.g\ (x\ x))\ (\lambda x.g\ (x\ x))</math>
| |
| |style="padding-left:30px;"| (by [[β-reduction]] of λf: applied Y to g)
| |
| |-
| |
| |
| |
| | <math>= g ((\lambda x.g\ (x\ x))\ (\lambda x.g\ (x\ x)))</math>
| |
| |style="padding-left:30px;"| (by β-reduction of λx: applied left function to right function)
| |
| |-
| |
| |
| |
| | <math>= g\ (Y\ g)</math>
| |
| |style="padding-left:30px;"| (by second equality)
| |
| |}
| |
| | |
| By repeatedly applying this equality we get,
| |
| : <math> Y\ g = g\ (Y\ g) = g\ (g\ (Y\ g)) = g\ (\ldots g\ (Y\ g) \ldots) </math>
| |
| | |
| ===Equivalent definition of a fix-point combinator===
| |
| | |
| An alternate definition of the fixed point combionator may be derived. Starting with a ''let'' expresion,
| |
| | |
| : <math> \operatorname{let} y\ f = f\ (y\ f) \operatorname{in} y </math>
| |
| | |
| Apply the reverse of an eta reduction; <math> g \equiv \lambda f.g\ f </math>,
| |
| : <math> \lambda f.\operatorname{let} y\ f = f\ (y\ f) \operatorname{in} y\ f </math>
| |
| | |
| The fixed point value is <math> y\ f = x </math>. After some derivation it is possible to show,
| |
| : <math> \lambda f.\operatorname{let} x = f\ x \operatorname{in} x </math>
| |
| | |
| This expression is equivalent to the following alternate definition of a fix-point combinator as ''y'' in,
| |
| : <math> y\ f = x \and x = f\ x</math>
| |
| | |
| ===Derivation of the Y combinator===
| |
| | |
| Curry's Y combinator may be readily obtained from the definition of ''x''.<ref>
| |
| http://math.stackexchange.com/questions/51246/can-someone-explain-the-y-combinator</ref>
| |
| Starting with,
| |
| : <math> \lambda f.\operatorname{let} x = f\ x \operatorname{in} x </math>
| |
| | |
| A lambda abstraction does not support reference to the variable name, in the applied expression, so ''x'' must be passed in as a parameter to ''x''.
| |
| : <math> \lambda f.\operatorname{let} x\ x = f\ (x\ x) \operatorname{in} x\ x </math>
| |
| | |
| Using the eta reduction rule,
| |
| : <math>f\ x = y \equiv f = \lambda x.y </math>
| |
| | |
| gives,
| |
| : <math> \lambda f.\operatorname{let} x = \lambda x.f\ (x\ x) \operatorname{in} x\ x </math>
| |
| | |
| A let expression may be expressed as a lambda abstraction using,
| |
| :<math> n \not \in FV(E) \to (\operatorname{let} n = E \operatorname{in} L \equiv (\lambda n.L)\ E) </math>
| |
| | |
| gives,
| |
| : <math> \lambda f.(\lambda x.x\ x)\ (\lambda x.f\ (x\ x)) </math>
| |
| | |
| This is possibly the simplest implementation of a fixed point combinator in lambda calculus. However one beta reduction gives the more symmetrical form of Curry's Y combinator.
| |
| : <math> \lambda f.(\lambda x.f\ (x\ x))\ (\lambda x.f\ (x\ x))</math>
| |
| | |
| See [[Lambda lifting]] on translating between recursive equations and Lambda calculus.
| |
| | |
| ===Other fixed-point combinators===
| |
| | |
| In untyped lambda calculus fixed-point combinators are not especially rare. In fact there are infinitely many of them.<ref name="bimbo">{{cite book|last=Bimbó|first=Katalin|title=Combinatory Logic: Pure, Applied and Typed|page=48|year=}}</ref> In 2005 Mayer Goldberg showed that the set of fixed-point combinators of untyped lambda calculus is [[recursively enumerable]].<ref name=gold>Goldberg, 2005</ref>
| |
| | |
| The ''Y'' combinator can be expressed in the [[SKI combinator calculus|SKI-calculus]] as
| |
| | |
| : ''Y'' = S (K (S I I)) (S (S (K S) K) (K (S I I)))
| |
| | |
| 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)
| |
| | |
| which corresponds to the lambda expression
| |
| | |
| : ''Y''' = (λx. λy. x y x) (λy. λx. y (x y x))
| |
| | |
| 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:
| |
| | |
| : ''X'' = λf.(λx.x x) (λx.f (x x))
| |
| | |
| Another common fixed point combinator is the Turing fixed-point combinator (named after its discoverer, [[Alan Turing]]):
| |
| | |
| : ''Θ'' = (λx. λy. (y (x x y))) (λx. λy. (y (x x y)))
| |
| | |
| It also has a simple call-by-value form:
| |
| | |
| : ''Θ''<sub>'''v'''</sub> = (λx. λy. (y (λz. x x y z))) (λx. λy. (y (λz. x x y z)))
| |
| | |
| The analog for [[mutual recursion]] is a ''polyvariadic fix-point combinator'',
| |
| <ref>[http://okmij.org/ftp/Computation/fixed-point-combinators.html#Poly-variadic Poly-variadic fix-point combinators]</ref><ref>[http://osdir.com/ml/lang.haskell.cafe/2003-10/msg00211.html Polyvariadic Y in pure Haskell98], lang.haskell.cafe, October 28, 2003
| |
| </ref><ref>[http://stackoverflow.com/questions/4899113/fixed-point-combinator-for-mutually-recursive-functions Fixed point combinator for mutually recursive functions?]</ref> which may be denoted Y*.
| |
| | |
| ===Strict fixed point combinator===
| |
| | |
| The ''Z'' combinator will work in strict languages (or where normal order is applied). The ''Z'' combinator has the next argument defined explicitly, preventing the expansion of ''Z'' g in the right hand side of the definition:
| |
| | |
| : ''Z'' g v = g (''Z'' g) v
| |
| | |
| and in lambda calculus is an eta-expansion:
| |
| | |
| : ''Z'' = λf.(λx.f (λv.((x x) v))) (λx.f (λv.((x x) v)))
| |
| | |
| === Non-standard fixed-point combinators ===
| |
| | |
| In untyped lambda calculus there are terms that have the same [[Böhm tree]] as a fixed-point combinator, that is they have the same infinite extension λx.x (x (x ... )). These 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 equation that defines the "standard" ones. These strange combinators are called ''strictly non-standard fixed-point combinators''; an example is the following combinator;
| |
| : N = B M (B (B M) B)
| |
| where,
| |
| : B = λx,y,z.x (y z)
| |
| : M = λx.x x
| |
| The set of non-standard fixed-point combinators is not recursively enumerable.<ref name=gold/>
| |
| | |
| ==Implementation in other languages==
| |
| | |
| Note that 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 the programming styles are given below.
| |
| | |
| For examples of implementations of the fixed point combinators in various languages see,
| |
| * [http://rosettacode.org/wiki/Y_combinator Rosetta code - Y combinator]
| |
| * [http://arcfn.com/2009/03/y-combinator-in-arc-and-java.html Java code].
| |
| * [http://stackoverflow.com/questions/152084/fixed-point-combinators-in-c/154267#154267 C++ code].
| |
| | |
| === Lazy functional implementation ===
| |
| | |
| 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 <code>fix</code>. The definition is given here, followed by some usage examples.
| |
| | |
| <source lang=Haskell>
| |
| fix :: (a -> a) -> a
| |
| fix f = f (fix f) -- non-sharing fixed-point, for recursive definitions
| |
| -- alternative:
| |
| -- fix f = let x = f x in x -- sharing fixed-point, for corecursive definitions
| |
|
| |
| fix (\x -> 9) -- this evaluates to 9
| |
| factabs fact 0 = 1 -- factabs is F from our lambda calculus example
| |
| factabs fact x = x * fact (x-1)
| |
| (fix factabs) 5 -- evaluates to 120
| |
| </source>
| |
| | |
| === Strict functional implementation ===
| |
| | |
| In a strict functional language the argument to ''f'' is expanded beforehand, yielding an infinite call sequence,
| |
| : <math>f\ (f ... f\ (\operatorname{fix}\ f)... ))\ x</math>.
| |
| | |
| This may be resolved by defining fix with an extra parameter.
| |
| | |
| <source lang=ocaml> | |
| let rec fix f x = f (fix f) x (* note the extra x; now fix f = \x-> f (fix f) x *)
| |
| | |
| let factabs fact = function (* factabs now has extra level of lambda abstraction *)
| |
| 0 -> 1
| |
| | x -> x * fact (x-1)
| |
| | |
| let _ = (fix factabs) 5 (* evaluates to "120" *)
| |
| </source>
| |
| | |
| ===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. | |
| | |
| <syntaxhighlight lang="cpp">
| |
| 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);
| |
| </syntaxhighlight>
| |
| | |
| ==Typing==
| |
| | |
| In [[polymorphic lambda calculus]] ([[System F]]) a polymorphic fixed-point combinator has type;
| |
| : ∀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 type]]s, 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]], a well-typed fixed-point combinator cannot be written. 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 type]]s (see [[System F-omega|System F<sub>ω</sub>]]), 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:<ref>Haskell mailing list thread on [http://groups.google.co.uk/group/fa.haskell/browse_frm/thread/f0a62b6de1416d8b How to define Y combinator in Haskell], 15 Sep 2006
| |
| </ref>
| |
| | |
| <source lang=haskell>
| |
| In :: (Rec a -> a) -> Rec a
| |
| out :: Rec a -> (Rec a -> a)
| |
| </source>
| |
| | |
| which lets us write: | |
| | |
| <source lang=haskell>
| |
| 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)))
| |
| </source>
| |
| | |
| Or equivalently in OCaml:
| |
| | |
| <source lang=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))
| |
| </source>
| |
| | |
| ==General information==
| |
| | |
| The function for which any input is a fixed point is called the [[identity function]]. Formally:
| |
| : <math>\forall x f\ x = x</math>
| |
| | |
| Other functions have the special property that after being applied once, further applications don't have any effect. More formally:
| |
| : <math>\forall x f\ f\ x = f\ x</math>
| |
| | |
| Such functions are called [[idempotent]]. An example of such a function is the function that returns ''0'' for all even integers, and ''1'' for all odd integers.
| |
| | |
| 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 (computer science)|recursion]] to be defined as a set of [[Production (computer science)|rewrite rule]]s,<ref>{{cite book|title=The Little Lisper|author=[[Daniel P. Friedman]], [[Matthias Felleisen]]|publisher=[[Science Research Associates]]|year=1986|chapter=Chapter 9 - Lambda The Ultimate|page=179}} "In the chapter we have derived a Y-combinator which allows us to write recursive functions of one argument withour using define."</ref> without requiring native recursion support in the language.<ref>{{cite web|url=http://mvanier.livejournal.com/2897.html|title=The Y Combinator (Slight Return) or: How to Succeed at Recursion Without Really Recursing|author=Mike Vanier}} "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."</ref>
| |
| | |
| The [[recursive join]] in [[relational databases]] implements a fixed point, by recursively adding records to a set until no more may be added.
| |
| | |
| In programming languages that support [[anonymous function]]s, fixed-point combinators allow the definition and use of anonymous [[recursion|recursive functions]], i.e. without having to [[Name binding|bind]] such functions to [[identifier]]s. In this setting, the use of fixed-point combinators is sometimes called ''[[anonymous recursion]]''.<ref>This terminology appear to be largely [[mathematical folklore|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<!--gives him credit!--> from [http://www.linkedin.com/pub/wes-dyer/2/727/a39 Wes Dyer]'s blog (see next item).
| |
| * Wes Dyer [http://blogs.msdn.com/wesdyer/archive/2007/02/02/anonymous-recursion-in-c.aspx Anonymous Recursion in C#], February 02, 2007, contains a substantially similar example found in the book above, but accompanied by more discussion.</ref><ref name=ifworks>The If Works [http://blog.jcoglan.com/2008/01/10/deriving-the-y-combinator/ Deriving the Y combinator], January 10th, 2008</ref>
| |
| | |
| ==See also==
| |
| | |
| * [[Fixed-point iteration]]
| |
| * [[Anonymous function]]
| |
| * [[Lambda calculus#Recursion and fixed points|Lambda calculus]]
| |
| * [http://rosettacode.org/wiki/Y_combinator Rosetta code - Y combinator]
| |
| | |
| ==Notes==
| |
| {{reflist}}
| |
| | |
| ==References==
| |
| * Werner Kluge, ''Abstract computing machines: a lambda calculus perspective'', Springer, 2005, ISBN 3-540-21146-2, pp. 73–77<!-- covers the how it works section, but does not use Wikipedia/Javascript/C# terminology like "anonymous recursion". -->
| |
| * Mayer Goldberg, (2005) ''[http://www.brics.dk/RS/05/1/BRICS-RS-05-1.pdf On the Recursive Enumerability of Fixed-Point Combinators]'', BRICS Report RS-05-1, University of Aarhus<!--covers most of the theory-->
| |
| * [[Matthias Felleisen]]. [http://www.ps.uni-sb.de/courses/sem-prog97/material/YYWorks.ps A Lecture on the ''Why'' of ''Y''].
| |
| | |
| ==External links==
| |
| {{wikibooks|Haskell/Fix and recursion}}
| |
| * http://www.latrobe.edu.au/philosophy/phimvt/joy/j05cmp.html
| |
| * http://okmij.org/ftp/Computation/fixed-point-combinators.html
| |
| * [http://matt.might.net/articles/implementation-of-recursive-fixed-point-y-combinator-in-javascript-for-memoization/ "Fixed-point combinators in Javascript"]
| |
| * http://www.cs.brown.edu/courses/cs173/2002/Lectures/2002-10-28-lc.pdf
| |
| * http://www.mactech.com/articles/mactech/Vol.07/07.05/LambdaCalculus/
| |
| * http://www.csse.monash.edu.au/~lloyd/tildeFP/Lambda/Examples/Y/ (executable)
| |
| * http://www.ece.uc.edu/~franco/C511/html/Scheme/ycomb.html
| |
| * [http://use.perl.org/~Aristotle/journal/30896 an example and discussion of a perl implementation]
| |
| * [http://www.ps.uni-sb.de/courses/sem-prog97/material/YYWorks.ps "A Lecture on the Why of Y"]
| |
| * [http://www.eecs.harvard.edu/~cduan/technical/ruby/ycombinator.shtml "A Use of the Y Combinator in Ruby"]
| |
| * [http://okasaki.blogspot.com/2008/07/functional-programming-inada.html "Functional programming in Ada"]
| |
| * [http://bc.tech.coop/blog/070611.html "Y Combinator in Erlang"]
| |
| * [http://kestas.kuliukas.com/YCombinatorExplained/ "The Y Combinator explained with JavaScript"]
| |
| * [http://mvanier.livejournal.com/2897.html "The Y Combinator (Slight Return)"] (detailed derivation)
| |
| * [http://yinwang0.wordpress.com/2012/04/09/reinvent-y "How to Reinvent The Y Combinator "] (animated slides)
| |
| * [http://blogs.msdn.com/b/madst/archive/2007/05/11/recursive-lambda-expressions.aspx "The Y Combinator in C#"]
| |
| | |
| {{DEFAULTSORT:Fixed Point Combinator}}
| |
| [[Category:Lambda calculus]]
| |
| [[Category:Mathematics of computing]]
| |
| [[Category:Fixed points (mathematics)]]
| |
| [[Category:Combinatory logic]]
| |
| [[Category:Recursion]]
| |