Talk:Fixed-point combinator

message: I saw Y defined in the top portion of the article, but I didn't find FIX defined, at least not by the time it was first used in a calculation.  I quickly tried using Y in place of FIX, but it did not seem to be working out.  —Preceding unsigned comment added by 71.126.226.201 (talk) 23:15, 26 December 2010 (UTC)
thread_title: Why is FIX not defined here?

message: Did anybody notice that the fixed point combinator by Klop as given here is wrong? Did anybody actually try it? I used it to test my lambda-calculus interpreter and I was thinking of a bug in it, until I found the correct definition somewhere on the web: 
(look for $). There should be 26 L's, not 28 as given here. The problem is that many web pages directly copy from the Wikipedia text, and give the same (wrong) definition. I don't know whether the page was vandalized long ago, or it was a genuine transcription error. Fixed. --positron 10:14, 7 March 2006 (UTC)
replies: text: I don't think anybody did try it.  Should've just removed it when I did a big cleanup a while back, I suppose.  Thanks for the fix.  —donhalcon╤ 14:52, 7 March 2006 (UTC)

text: For those who will be searching for this in the future: the error comes from Klop’s original article, where this combinator has 28 Ls. Kirelagin (talk) 11:29, 16 September 2015 (UTC)
thread_title: Klop combinator

message: Could you dumb it down a shade?
--Mike Schiraldi 01:53, 27 Jun 2005 (UTC)
replies: text: I've submitted a rewrite that should be a lot easier to understand. --bmills 18:00, 21 October 2005 (UTC)
thread_title: Dumbing Down

message: It seems like the Y Combinator should have its own page.
:No it doesn't.  —Preceding unsigned comment added by 98.108.198.154 (talk) 05:53, 8 March 2011 (UTC)
replies: text: excellent argument. "Y combinator" is a term I have run into three times in the past few weeks, and I found better explanations of it elsewhere. Thanks wiki. You suck. More nerds talking to themselves rather than being informative.  — Preceding unsigned comment added by 72.92.6.251 (talk) 05:20, 8 September 2012 (UTC)
replies: text: There is nothing magic about Wikipedia (except possibly the magic put into it by generous people donating their knowledge and editing skills). There are certainly articles here that are just plain unhelpful to many readers. If you have found better explanations elsewhere, and don't bother to point to them, then you are not being at all helpful in making WP better (which is at the heart of your own criticism). Sorry that I am posting this four years later, when you are no doubt gone, but I share your frustration when reading unhelpful articles. I only wish you had chosen to help us instead of limiting yourself to criticism. David Spector (talk) 01:12, 16 April 2016 (UTC)
thread_title: Y Combinator

message: Why does the example mix (a b (c d)) and a(b)(c(d)) notation? It would be a lot clearer, I think, if it stuck to (a b (c d)), and put ( ) on the lambdas as well. It would also be nice to state the final result (fact = (fix ...)). Shinobu 06:57, 8 November 2006 (UTC)
thread_title:  Example 

message: :Note that the Y combinator is intended for the call-by-name evaluation strategy, since (Y g) diverges (for any g) in call-by-value settings
Can somebody explain this?  What does call-by-name versus call-by-value even mean in the context of lambda calculus?  Isn't call-by-name always the case in lambda calculus?  Why does Y g diverge in call-by-value?  What does 'diverge' mean in this context?  All these things are totally non-obvious. JulesH 19:12, 11 November 2007 (UTC)
replies: text: What call-by-value means is explained at the given evaluation strategy link. The context is evaluation of lambda expressions in real programming languages on real machines. call-by-value requires the evaluation of all of a function's arguments before the function itself is evaluated -- even if evaluation of the function doesn't require some of the arguments. Evaluation of such arguments might not terminate -- it might even diverge if, say, the evaluation creates a lambda expression which in turn becomes the argument to an evaluation ad infinitum, creating larger and larger lambda expressions. -- 98.108.198.154 (talk) 06:43, 8 March 2011 (UTC)
thread_title:  Huh? 

message: Both examples for the Y combinator use functional languages, which support Currying. This means that the given examples can not simply be translated to other languages which support first-class functions, but no currying/partial exaluation.
Here is an example in Ruby of the y combinator and its use with factorial. It explicitly uses an additional function which takes the arguments for our original function, apart from that, it is a direct translation of the y combinator's definition.
Maybe we could try to improve it a little / make it more readable (at least add proper indendation) and then incorporate it into the article.
y = lambda { |f| (lambda { |x| lambda { |*args| (f.call(x.call(x))).call(*args) }}).call(lambda { |x| lambda { |*args| (f.call(x.call(x))).call(*args) }})}
b = y.call(lambda { |f| lambda {|i| if i == 0 then 1 else i * (f.call(i-1)) end }})
puts(b.call 5) # 120
Subwy (talk) 10:58, 10 December 2008 (UTC)
thread_title:  Further examples 

message: One really good demonstration of how the Y combinator works (it has enough hand waving to make the general principles accessible to the layman), is this:
       let Y = (lambda (f)
                 ((lambda (g) (f (g g)))
                  (lambda (g) (f (g g)))))
       let H = (lambda (g) (f (g g))) for convenience
   
       let fact = (Y fact-h)  
   
          fact 
       => (Y fact-h)
       => (H H)      ; with f = fact-h
       => (fact-h (g g))
       => (fact-h (H H))
       =  (fact-h (Y fact-h))
       =  (fact-h fact)
   
       ;; => indicates a substitution step, while = indicates an equivalence
       ;; which is not actually a substitution
Unfortunately, this uses a lispy syntax, which most people are not familiar with. We should work this into something that could go into the article. — Edward Z. Yang(Talk) 06:23, 29 January 2009 (UTC)
thread_title:  Some material 

message: Technically the Haskell definition is the equation that defines any fixed point combinator no? So why is it Y? Pcap ping 04:51, 21 August 2009 (UTC)
replies: text: Well, that was incorrect, so I've fixed it. Pcap ping 21:33, 21 August 2009 (UTC)
thread_title:  Why is the Haskell Y the Y combinator? 

message: Functions in lambda calculus don't have a name, so that statement is nonsensical in the context of lambda calculus. To make some sense you need to specify some formal language where you can/must have names for some functions. But the example that is supposed to clarify the meaning of "anonymous" (as opposed to named) is in lambda calculus, where all functions are anonymous! The anonymous (like all other!) function returned by Y (i.e. factorial) is indeed a primitive recursive function, but all μ-recursive functions are lambda definable (see a theory book for proof, e.g. ), so what are you trying to say here? Pcap ping 05:38, 21 August 2009 (UTC)
replies: text: I think I've clarified the matter. Pcap ping 07:22, 21 August 2009 (UTC)

text: It is true that the only form of recursion in lambda calculus is anonymous recursion (since there are no functions names). But for most people in other languages, they are only familiar with recursion by explicitly using the function name. The very concept of anonymous recursion is surprising to many people. It is therefore informative to tell them that fixed point combinators is the mechanism by which anonymous recursion is done (and specifically "anonymous" recursion, to distinguish it from the recursion that they are familiar with). Fixed point combinators are not just for lambda calculus, but also other languages too. --76.173.203.32 (talk) 04:31, 22 August 2009 (UTC)
replies: text:  This was mentioned in the lead, with references, and I now added another paragraph that delves on the matter in the "how it works" section. There's also a (short, because it's somewhat off-topic) section describing alternative solutions to the problem of anonymous recursion. Pcap ping 08:37, 22 August 2009 (UTC)
thread_title:  "Fixed point combinators allow the definition of anonymous recursive functions" 

message: The opening sentence of this article is: "A fixed-point combinator (or fixpoint combinator) is a higher-order function that computes a fixed point of other functions." 
I think it would be better preceded with a couple of words specifying which academic field this subject falls under. Eg "In computer science, a fixed-point combinator..." Or perhaps "In mathematics..." or "In logic theory..." (I don't know which is most appropriate, or I'd add it myself.) 
Without any context, the opening sentence seems a bit obscure and esoteric, if you're unfamiliar with the subject (like me). Denbosch (talk) 11:31, 10 November 2011 (UTC)
replies: text: Done. —Ruud 15:14, 10 November 2011 (UTC)
thread_title:  Can we set out the field at the beginning? 

message: There are two fix point combinators in Haskell, one is code-replicating, another is through sharing:
fix f = f (fix f)
fix f = x where x = f x
The second one lends itself naturally to corecursive definitions, like
fibs = fix ((0:) . (1:) . next) 
  where 
    next (a:t@(b:_)) = (a+b):next t
Used w/ the first fix, it still works though runs in quadratic time.
Can/should/how can this be incorporated into the article? – WillNess (talk) 21:54, 11 November 2011 (UTC)
thread_title:  Corecursive fix 

message: Here's a tested PHP 5.4 implementation for the Y Combinator function:
function Y(callable $f)
{
	$funcA = function ($x) use ($f)
	{
		return $f(function ($v) use ($x)
		{
			$funcB = ($x($x));
			return $funcB($v);
		}); 
	};
    return $funcA($funcA);
}
And the factorial example applied to it:
$factorial = Y(
	function ($fac)
	{
		return function ($n) use ($fac)
		{
			if ($n === 0) {
				return 1;
			} else { 
				return $n * $fac($n - 1);
			}
		};
	}
);
$result = $factorial(5); // 120
Jazzer7 (talk) 06:51, 6 June 2012 (UTC)
thread_title:  PHP Example 

message: Something that has bothered me about many of the articles regarding lambda calculus. There is a tendency to make examples a massive cludge from lots of different program languages that do not add any encyclopedic value to the content of the article. Everyone looks at an article, and says, "My favorite language isn't represented here!" and then adds it. 
In the last few weeks, I noticed two additions to this article list of examples (C-sharp and Javascript). These are useless examples. I'm always a little weary getting rid of content, but this every growing list of examples has to stop. It violates WP:NOT on indiscriminate lists; in particular, it is a list of information which was gathered in a thoughtless manner not consistent with expanding the encyclopedic value of the article. 
Examples are good however. So I propose that we leave two examples. One from a procedural language and one from a functional language. I think the best ones to leave are Python (because it's very human-readable) and ML, which for some reason isn't even on the article despite being of the greatest theoretical importance (probably because you need to use let rec...). I would be bold, but I'm a little hesitant to alter so many people's edits without giving a chance for people to tell me why they believe this isn't a indiscriminate list of information. So without other suggestions, I will make my proposed changes soon.    Wgunther (talk) 14:32, 25 November 2012 (UTC)
replies: text: This is a problem across many computer science articles, I like to call it "language creep". The only solution it to prune mercylessly, preferably leaving only a single example in a non-real language like PCF or psuedo-ML. Also, the section should under not be called "Example in <language X>", this is too big of an invitiation to add an additional section "Example in <language Y>", and so on. Occasionally it might be useful to add a link to Wikibooks or Rosetta Code with more examples. —Ruud 16:07, 25 November 2012 (UTC)
replies: text: I agree: prune heavily to just the one or two best examples. No need for a gallery of languages. — Carl (CBM · talk) 19:31, 25 November 2012 (UTC)
replies: text: Seconded. Especially glad to see the C-sharp version amended/removed, since it uses named recursion (the Y function calls the Y function) which defeats the point. Plus it's type annotations make it look a mess ;) 87.194.139.125 (talk) 20:55, 30 November 2012 (UTC)

text: I took out all the examples written in the form of a code repository, citing MOS:CODE a month ago. Now I'm getting some undos, with no edit summary and no discussion, and no attempt to reformat and pick examples that actually increase the encyclopedic nature of the article. I'm not willing to do this, because I don't think any of the example eliminated have encyclopedic nature, and believe a consensus was reached about these examples as well. I'm assuming good faith, but I will enforce my elimination without new talk or at least an edit summary on the undo. Wgunther (talk) 23:25, 11 January 2013 (UTC)
replies: text: I think we should return most of the code examples (excl. wrong ones, as C#). While it's the case that they do not add any encyclopedic value, I find them really useful when one tries to grasp anonymous recursion. They may provide better background for understanding somewhat more abstract way of implementing recursion with y-combinator  serving as quick how-it's-done reference than more theoretically-inclined lambda calculus or ML/Haskell - imo most people comfort with these languages already have sound theoretical foundations and concrete code example adds little or no benefit. I suggest keeping at least Python/Javascript and Scheme/Lisp. БръмБръм (talk) 13:40, 14 February 2013 (UTC)
thread_title:  Examples Gathered Indiscriminately 

message: Under "Explanation for imperative programmers", it is stated that "It is difficult and confusing to try to write fixed_point() in imperative terms, so we will not attempt it."
However, the example there can be fixed to address this (if I am not mistaken), without the explicit introduction of a general fixed-point combinator for that language, i.e., it can be changed to show how a non-iterative, non-recursive solution can be programmed. How about this rewrite (changes in bold):
:How is a recursive function written in these languages?  It is done by breaking the function into two parts.  The first part looks very similar to the recursive version of the function.  The difference is that it takes a function as a parameter and calls that parameter instead of calling itself recursively.  (Remember, functions are values so they can be passed as arguments to functions.  This isn't often done in imperative programming.)
:
 factorial_helper(function foo, integer n) {    --- added function as a parameter
   if n=0 then
     return 1;
   else
     return n * foo(foo, n-1);   --- recursive call replaced with call to parameter
 }
:
:Now, if that function parameter was "factorial", then this helper function would calculate the factorial.  So, the second part of building the recursive function is to create a function "factorial" and set it equal to "factorial_helper" with "factorial_helper" as the first parameter.
:
 factorial(integer n) { 
   factorial_helper(factorial_helper, n)   --- "factorial_helper" is passed as the function parameter to itself
 }
:
Now, the subsequent paragraph can be deleted:
:This doesn't quite work because we've run into the same problem as before: the function "factorial" is using its value before we get to the end of its definition.  The fixed-point function solves this for us.  Due to its special structure, it is able to call "factorial_helper" recursively without using a value before it is defined.  The fixed point function takes the helper as an argument and returns the recursive function.  (Remember functions are values - they can be passed as arguments and returned by functions.)
:
 factorial = fixed_point(factorial_helper)
:
:It is difficult and confusing to try to write fixed_point() in imperative terms, so we will not attempt it.
:
Instead, it can be pointed out that this specific solution could be obtained via a general fixed-point combinator, which can also be used for other recursive definitions, rather than relying on ad hoc solutions (for the fixed point).
Wstomv (talk) 20:34, 26 August 2013 (UTC)
replies: text: What you've given is a (correct) way to define a fixed point (for factorial), but it is still "difficult and confusing" to try to write "the" fixed_point (i.e. the function). Haklo (talk) 23:50, 9 January 2014 (UTC)
thread_title:  Why no detail for imperative language w/o recursion? 

message: Does this work?  It doesn't involve a fixpoint combinator (or does it?).
factorial_helper(function foo, integer n) {
  if n=0 then
    return 1;
  else
    return n * foo(foo, n - 1);
}
factorial(n) {
  return factorial_helper(factorial_helper, n)
}
If this is a valid way to do anonymous recursion, why do we need fixpoint combinators to do this?  — Preceding unsigned comment added by 18.111.28.55 (talk) 17:57, 14 November 2013 (UTC)
thread_title:  Simpler way to do anonymous recursion? 

message: I have done a little bit of editorial work mainly moving stuff around and trying to organize things.  If something important to you has been lost add a note here.  I hope the changes are acceptable for everybody.
Thepigdog (talk) 05:06, 16 January 2014 (UTC)
thread_title: Minor changes

message: 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
Are the comments correct???  From my reading, the two forms have nothing to do with recursion and corecursion.  Both are recursive definitions; one is the lifted form of the other.
Thepigdog (talk) 03:41, 4 February 2014 (UTC)
thread_title: Recursion / Corecursion

message: I don't see enough merit in having yet another C++ example. This is not a collection of different implementations of the Y combinator.  See rosettacode.org for that.  So I have taken it out.
If I was to be picky I would say.
* Y combinator should be templated (not int -> int).
* Dont need main (so remove iostream, cassert)
But you do all that and it still adds nothing to the understanding of the Y combinator. Sorry.
#include <functional>
#include <iostream>
#include <cassert>
 
using std::function;
// Y-combinator compatible factorial
int fact(function<int(int)> f,int v)
{
  if(v == 0)
    return 1;
  else
    return v * f(v -1);
}
 
// Y-combinator for the int type
function<int(int)>
    y(function<int(function<int(int)>,int)> f)
{
  return [=](int x) {
    return f(y(f), x);  
  };
}
 
int main(void)
{
  function<int(int)> factorial = y(fact);
  assert(y(fact)(5) == fact(y(fact), 5));
  std::cout << factorial(5) << std::endl;
  return 0;
}
Thepigdog (talk) 05:39, 30 October 2014 (UTC)
thread_title: Another C++ example

message: I think this example does not add anything. Perhaps you would like to add it to,
* http://rosettacode.org/wiki/Y_combinator
For example, a Y-combinator implementation of factorial in the Wolfram Language would be
Y = Function[f, #[#]&[Function[g, f[g[g][##]&]]]];
factorial = Y[Function[f, If[# < 1, 1, # f[# - 1]] &]];
factorial[6] (*Yields 120*)
Thepigdog (talk) 02:20, 26 May 2015 (UTC)
thread_title:  Wolfram example 

message: Hello fellow Wikipedians,
I have just modified 2 external links on Fixed-point combinator. Please take a moment to review my edit. If you have any questions, or need the bot to ignore the links, or the page altogether, please visit this simple FaQ for additional information. I made the following changes:
*Added archive https://web.archive.org/web/20110822202348/http://mvanier.livejournal.com/2897.html to http://mvanier.livejournal.com/2897.html
*Added archive https://web.archive.org/web/20110822202348/http://mvanier.livejournal.com/2897.html to http://mvanier.livejournal.com/2897.html
When you have finished reviewing my changes, you may follow the instructions on the template below to fix any issues with the URLs.
Cheers.—InternetArchiveBot (Report bug) 19:07, 5 April 2017 (UTC)
thread_title:  External links modified 

message: I fixed some parts, later I saw here, some comments proposing similar fixes.
I think  that the main problem of this article is that it seems to be based in some notes about scheme.
Scheme is based on lambda calculus, it is not lambda calculus.
In lambda calculus nor combinator logic, one can't write recursive definitions like fact x = if x=0 then 1 else x*fact (x-1)
that is the reason for a fixed point combinator.  — Preceding unsigned comment added by 201.124.239.99 (talk) 13:25, 25 April 2017 (UTC)
thread_title:  Needs to be rewritten,  or a very good review 

message: Hello fellow Wikipedians,
I have just modified 4 external links on Fixed-point combinator. Please take a moment to review my edit. If you have any questions, or need the bot to ignore the links, or the page altogether, please visit this simple FaQ for additional information. I made the following changes:
*Added archive https://web.archive.org/web/20140408014716/http://cs.anu.edu.au/courses/COMP3610/lectures/Lambda.pdf to http://cs.anu.edu.au/courses/COMP3610/lectures/Lambda.pdf
*Added archive https://web.archive.org/web/20090113202334/http://www.latrobe.edu.au/philosophy/phimvt/joy/j05cmp.html to http://www.latrobe.edu.au/philosophy/phimvt/joy/j05cmp.html
*Added archive https://web.archive.org/web/20061110043130/http://use.perl.org/~Aristotle/journal/30896 to http://use.perl.org/~Aristotle/journal/30896
*Added archive https://web.archive.org/web/20090314203740/http://bc.tech.coop/blog/070611.html to http://bc.tech.coop/blog/070611.html
When you have finished reviewing my changes, you may follow the instructions on the template below to fix any issues with the URLs.
Cheers.—InternetArchiveBot (Report bug) 22:11, 1 October 2017 (UTC)
thread_title:  External links modified 

message: Hello fellow Wikipedians,
I have just modified one external link on Fixed-point combinator. Please take a moment to review my edit. If you have any questions, or need the bot to ignore the links, or the page altogether, please visit this simple FaQ for additional information. I made the following changes:
*Added archive https://web.archive.org/web/20160304101809/http://osdir.com/ml/lang.haskell.cafe/2003-10/msg00211.html to http://osdir.com/ml/lang.haskell.cafe/2003-10/msg00211.html
When you have finished reviewing my changes, you may follow the instructions on the template below to fix any issues with the URLs.
Cheers.—InternetArchiveBot (Report bug) 23:08, 21 January 2018 (UTC)
thread_title:  External links modified (January 2018) 

message: This is mostly about the "values and domains" section, but there are also various other comments scattered throughout the article that I think need clearing up.
I'm not an expert, but it seems to me that there are at least two ways to think about the semantics of untyped lambda calculus. One is the "domain" approach, explained (though not very clearly) in the linked Deductive lambda calculus article. In this interpretation every lambda expression has a value, even the non-halting ones. But there is also the more obvious semantics where each lambda expression is a partial function. It has a value if it beta reduces to a normal form, but otherwise it doesn't have a value. I believe that both of these are consistent and it's really a matter of choice which one to use.
The issue is that the article sometimes talks in terms of one and sometimes in terms of the other. For example, in the lede it states
: a fixed-point combinator (or fixpoint combinator) is a higher-order function that returns some fixed point of its argument function, if one exists.
This sounds like it's taking the partial function view: the argument function might not have a fixed point, and in that case the fixed-point combinator doesn't return a value.
(Though now I come to think of it, this statement is not actually correct. Consider the Y combinator applied to the identity function. It's easy to see that no value is returned in this case, even though any lambda term at all is a fixed point of the identity function. I guess the correct statement would be that it returns some fixed point of its argument function if it halts.)
On the other hand the article also makes statements like
: In the classical untyped lambda calculus, every function has a fixed point
which seems to me to be true in the domain interpretation but not in the partial function interpretation. (Although I could be wrong about that.) It also makes statements like
: Every expression has one value. This is true in general mathematics and it must be true in lambda calculus.
Which seems like it's trying to justify the domain semantics as the only true semantics of the lambda calculus. But really it's just a false statement, since there's nothing to stop you defining a system where an expression might have many or no values, and the partial function semantics is such a system (I think).
So it seems to me that the article has sort of mixed up two different views about the semantics of the lambda calculus and also tried to present one of them as the only semantics, without flagging up that this is a choice. I would try to fix this myself but I don't feel I have the expertise to be sure I'm getting it right - I'm just mentioning this because I think it needs attention from someone who knows what they're doing.
Nathaniel Virgo (talk) 04:28, 17 October 2023 (UTC)
thread_title:  Confusing/contradictory claims about lambda calculus semantics