Y combinator: Difference between revisions

Content added Content deleted
m (syntax highlighting fixup automation)
Line 22: Line 22:
=={{header|AArch64 Assembly}}==
=={{header|AArch64 Assembly}}==
{{works with|as|Raspberry Pi 3B version Buster 64 bits}}
{{works with|as|Raspberry Pi 3B version Buster 64 bits}}
<syntaxhighlight lang="aarch64 assembly">
<lang AArch64 Assembly>
/* ARM assembly AARCH64 Raspberry PI 3B */
/* ARM assembly AARCH64 Raspberry PI 3B */
/* program Ycombi64.s */
/* program Ycombi64.s */
Line 287: Line 287:
/* for this file see task include a file in language AArch64 assembly */
/* for this file see task include a file in language AArch64 assembly */
.include "../includeARM64.inc"
.include "../includeARM64.inc"
</syntaxhighlight>
</lang>


=={{header|ALGOL 68}}==
=={{header|ALGOL 68}}==
Line 296: Line 296:
{{wont work with|ELLA ALGOL 68|Any (with appropriate job cards) - tested with release [http://sourceforge.net/projects/algol68/files/algol68toc/algol68toc-1.8.8d/algol68toc-1.8-8d.fc9.i386.rpm/download 1.8-8d] - compile not currently available on my system.}}
{{wont work with|ELLA ALGOL 68|Any (with appropriate job cards) - tested with release [http://sourceforge.net/projects/algol68/files/algol68toc/algol68toc-1.8.8d/algol68toc-1.8-8d.fc9.i386.rpm/download 1.8-8d] - compile not currently available on my system.}}
{{wont work with|ALGOL 68G|Any - tested with release [http://sourceforge.net/projects/algol68/files/algol68g/algol68g-1.18.0/algol68g-1.18.0-9h.tiny.el5.centos.fc11.i386.rpm/download 1.18.0-9h.tiny] - correctly detects a scope violation}} -->
{{wont work with|ALGOL 68G|Any - tested with release [http://sourceforge.net/projects/algol68/files/algol68g/algol68g-1.18.0/algol68g-1.18.0-9h.tiny.el5.centos.fc11.i386.rpm/download 1.18.0-9h.tiny] - correctly detects a scope violation}} -->
<lang algol68>BEGIN
<syntaxhighlight lang="algol68">BEGIN
MODE F = PROC(INT)INT;
MODE F = PROC(INT)INT;
MODE Y = PROC(Y)F;
MODE Y = PROC(Y)F;
Line 306: Line 306:


FOR i TO 10 DO print(y(fib)(i)) OD
FOR i TO 10 DO print(y(fib)(i)) OD
END</lang>
END</syntaxhighlight>
<!--
<!--
ALGOL 68G Output demonstrating the runtime scope violation:
ALGOL 68G Output demonstrating the runtime scope violation:
Line 325: Line 325:
These could easily be fixed by changing names, but I believe that doing so would make the code harder to follow.
These could easily be fixed by changing names, but I believe that doing so would make the code harder to follow.


<lang algol68>BEGIN
<syntaxhighlight lang="algol68">BEGIN


# This version needs partial parameterisation in order to work #
# This version needs partial parameterisation in order to work #
Line 401: Line 401:
print( newline )
print( newline )


END</lang>
END</syntaxhighlight>


=={{header|AppleScript}}==
=={{header|AppleScript}}==
Line 411: Line 411:


The identifier used for Y uses "pipe quoting" to make it obviously distinct from the y used inside the definition.
The identifier used for Y uses "pipe quoting" to make it obviously distinct from the y used inside the definition.
<lang AppleScript>-- Y COMBINATOR ---------------------------------------------------------------
<syntaxhighlight lang="applescript">-- Y COMBINATOR ---------------------------------------------------------------


on |Y|(f)
on |Y|(f)
Line 507: Line 507:
end script
end script
end if
end if
end mReturn</lang>
end mReturn</syntaxhighlight>
{{Out}}
{{Out}}
<lang AppleScript>{facts:{1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880, 3628800, 39916800},
<syntaxhighlight lang="applescript">{facts:{1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880, 3628800, 39916800},
fibs:{0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181, 6765}}</lang>
fibs:{0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181, 6765}}</syntaxhighlight>


=={{header|ARM Assembly}}==
=={{header|ARM Assembly}}==
{{works with|as|Raspberry Pi}}
{{works with|as|Raspberry Pi}}
<syntaxhighlight lang="arm assembly">
<lang ARM Assembly>


/* ARM assembly Raspberry PI */
/* ARM assembly Raspberry PI */
Line 767: Line 767:
.include "../affichage.inc"
.include "../affichage.inc"


</syntaxhighlight>
</lang>
{{output}}
{{output}}
<pre>
<pre>
Line 797: Line 797:


=={{header|ATS}}==
=={{header|ATS}}==
<syntaxhighlight lang="ats">
<lang ATS>
(* ****** ****** *)
(* ****** ****** *)
//
//
Line 822: Line 822:
//
//
(* ****** ****** *)
(* ****** ****** *)
</syntaxhighlight>
</lang>


=={{header|BlitzMax}}==
=={{header|BlitzMax}}==
BlitzMax doesn't support anonymous functions or classes, so everything needs to be explicitly named.
BlitzMax doesn't support anonymous functions or classes, so everything needs to be explicitly named.
<lang blitzmax>SuperStrict
<syntaxhighlight lang="blitzmax">SuperStrict


'Boxed type so we can just use object arrays for argument lists
'Boxed type so we can just use object arrays for argument lists
Line 981: Line 981:


Local fib:Func = Func(_Y.apply([FibL1.lambda(Null)]))
Local fib:Func = Func(_Y.apply([FibL1.lambda(Null)]))
Print Integer(fib.apply([Integer.Make(10)])).val</lang>
Print Integer(fib.apply([Integer.Make(10)])).val</syntaxhighlight>


=={{header|Bracmat}}==
=={{header|Bracmat}}==
Line 999: Line 999:
<pre>(Y H) i</pre>
<pre>(Y H) i</pre>
where i varies between 1 and 10, are translated into Bracmat as shown below
where i varies between 1 and 10, are translated into Bracmat as shown below
<lang bracmat>( ( Y
<syntaxhighlight lang="bracmat">( ( Y
= /(
= /(
' ( g
' ( g
Line 1,042: Line 1,042:
)
)
&
&
)</lang>
)</syntaxhighlight>
{{out}}
{{out}}
<pre>1!=1
<pre>1!=1
Line 1,066: Line 1,066:


=={{header|C}}==
=={{header|C}}==
C doesn't have first class functions, so we demote everything to second class to match.<lang C>#include <stdio.h>
C doesn't have first class functions, so we demote everything to second class to match.<syntaxhighlight lang="c">#include <stdio.h>
#include <stdlib.h>
#include <stdlib.h>


Line 1,136: Line 1,136:
return 0;
return 0;
}
}
</syntaxhighlight>
</lang>


{{out}}
{{out}}
Line 1,150: Line 1,150:
''Note: in the code, <code>Func<T, TResult></code> is a delegate type (the CLR equivalent of a function pointer) that has a parameter of type <code>T</code> and return type of <code>TResult</code>. See [[Higher-order functions#C#]] or [https://docs.microsoft.com/en-us/dotnet/standard/delegates-lambdas the documentation] for more information.''
''Note: in the code, <code>Func<T, TResult></code> is a delegate type (the CLR equivalent of a function pointer) that has a parameter of type <code>T</code> and return type of <code>TResult</code>. See [[Higher-order functions#C#]] or [https://docs.microsoft.com/en-us/dotnet/standard/delegates-lambdas the documentation] for more information.''


<lang csharp>using System;
<syntaxhighlight lang="csharp">using System;


static class YCombinator<T, TResult>
static class YCombinator<T, TResult>
Line 1,172: Line 1,172:
}
}
}
}
</syntaxhighlight>
</lang>
{{out}}
{{out}}
<pre>3628800
<pre>3628800
Line 1,178: Line 1,178:


Alternatively, with a non-generic holder class (note that <code>Fix</code> is now a method, as properties cannot be generic):
Alternatively, with a non-generic holder class (note that <code>Fix</code> is now a method, as properties cannot be generic):
<lang csharp>static class YCombinator
<syntaxhighlight lang="csharp">static class YCombinator
{
{
private delegate Func<T, TResult> RecursiveFunc<T, TResult>(RecursiveFunc<T, TResult> r);
private delegate Func<T, TResult> RecursiveFunc<T, TResult>(RecursiveFunc<T, TResult> r);
Line 1,184: Line 1,184:
public static Func<T, TResult> Fix<T, TResult>(Func<Func<T, TResult>, Func<T, TResult>> f)
public static Func<T, TResult> Fix<T, TResult>(Func<Func<T, TResult>, Func<T, TResult>> f)
=> ((RecursiveFunc<T, TResult>)(g => f(x => g(g)(x))))(g => f(x => g(g)(x)));
=> ((RecursiveFunc<T, TResult>)(g => f(x => g(g)(x))))(g => f(x => g(g)(x)));
}</lang>
}</syntaxhighlight>


Using the late-binding offered by <code>dynamic</code> to eliminate the recursive type:
Using the late-binding offered by <code>dynamic</code> to eliminate the recursive type:
<lang csharp>static class YCombinator<T, TResult>
<syntaxhighlight lang="csharp">static class YCombinator<T, TResult>
{
{
public static Func<Func<Func<T, TResult>, Func<T, TResult>>, Func<T, TResult>> Fix { get; } =
public static Func<Func<Func<T, TResult>, Func<T, TResult>>, Func<T, TResult>> Fix { get; } =
f => ((Func<dynamic, Func<T, TResult>>)(g => f(x => g(g)(x))))((Func<dynamic, Func<T, TResult>>)(g => f(x => g(g)(x))));
f => ((Func<dynamic, Func<T, TResult>>)(g => f(x => g(g)(x))))((Func<dynamic, Func<T, TResult>>)(g => f(x => g(g)(x))));
}</lang>
}</syntaxhighlight>


The usual version using recursion, disallowed by the task (implemented as a generic method):
The usual version using recursion, disallowed by the task (implemented as a generic method):
<lang csharp>static class YCombinator
<syntaxhighlight lang="csharp">static class YCombinator
{
{
static Func<T, TResult> Fix<T, TResult>(Func<Func<T, TResult>, Func<T, TResult>> f) => x => f(Fix(f))(x);
static Func<T, TResult> Fix<T, TResult>(Func<Func<T, TResult>, Func<T, TResult>> f) => x => f(Fix(f))(x);
}</lang>
}</syntaxhighlight>


===Translations===
===Translations===
Line 1,206: Line 1,206:


'''Verbatim'''
'''Verbatim'''
<lang csharp>using Func = System.Func<int, int>;
<syntaxhighlight lang="csharp">using Func = System.Func<int, int>;
using FuncFunc = System.Func<System.Func<int, int>, System.Func<int, int>>;
using FuncFunc = System.Func<System.Func<int, int>, System.Func<int, int>>;


Line 1,246: Line 1,246:
return 0;
return 0;
}
}
}</lang>
}</syntaxhighlight>


'''Semi-idiomatic'''
'''Semi-idiomatic'''
<lang csharp>using System;
<syntaxhighlight lang="csharp">using System;


using FuncFunc = System.Func<System.Func<int, int>, System.Func<int, int>>;
using FuncFunc = System.Func<System.Func<int, int>, System.Func<int, int>>;
Line 1,275: Line 1,275:
Console.WriteLine("fac(10) = " + fac(10));
Console.WriteLine("fac(10) = " + fac(10));
}
}
}</lang>
}</syntaxhighlight>


====[http://rosettacode.org/mw/index.php?oldid=287744#Ceylon Ceylon]====
====[http://rosettacode.org/mw/index.php?oldid=287744#Ceylon Ceylon]====
Line 1,283: Line 1,283:


'''Verbatim'''
'''Verbatim'''
<lang csharp>using System;
<syntaxhighlight lang="csharp">using System;
using System.Diagnostics;
using System.Diagnostics;


Line 1,330: Line 1,330:
Console.WriteLine(fibY1(10)); // 110
Console.WriteLine(fibY1(10)); // 110
}
}
}</lang>
}</syntaxhighlight>


'''Semi-idiomatic'''
'''Semi-idiomatic'''
<lang csharp>using System;
<syntaxhighlight lang="csharp">using System;
using System.Diagnostics;
using System.Diagnostics;


Line 1,376: Line 1,376:
Console.WriteLine(fibY1(10));
Console.WriteLine(fibY1(10));
}
}
}</lang>
}</syntaxhighlight>


====[http://rosettacode.org/mw/index.php?oldid=287744#Go Go]====
====[http://rosettacode.org/mw/index.php?oldid=287744#Go Go]====
Line 1,382: Line 1,382:


'''Verbatim'''
'''Verbatim'''
<lang csharp>using System;
<syntaxhighlight lang="csharp">using System;


// Func and FuncFunc can be defined using using aliases and the System.Func<T, TReult> type, but RecursiveFunc must be a delegate type of its own.
// Func and FuncFunc can be defined using using aliases and the System.Func<T, TReult> type, but RecursiveFunc must be a delegate type of its own.
Line 1,424: Line 1,424:
};
};
}
}
}</lang>
}</syntaxhighlight>


Recursive:
Recursive:
<lang csharp> static Func Y(FuncFunc f) {
<syntaxhighlight lang="csharp"> static Func Y(FuncFunc f) {
return delegate (int x) {
return delegate (int x) {
return f(Y(f))(x);
return f(Y(f))(x);
};
};
}</lang>
}</syntaxhighlight>


'''Semi-idiomatic'''
'''Semi-idiomatic'''
<lang csharp>using System;
<syntaxhighlight lang="csharp">using System;


delegate int Func(int i);
delegate int Func(int i);
Line 1,456: Line 1,456:


static Func almost_fib(Func f) => x => x <= 2 ? 1 : f(x - 1) + f(x - 2);
static Func almost_fib(Func f) => x => x <= 2 ? 1 : f(x - 1) + f(x - 2);
}</lang>
}</syntaxhighlight>


Recursive:
Recursive:
<lang csharp> static Func Y(FuncFunc f) => x => f(Y(f))(x);</lang>
<syntaxhighlight lang="csharp"> static Func Y(FuncFunc f) => x => f(Y(f))(x);</syntaxhighlight>


====[http://rosettacode.org/mw/index.php?oldid=287744#Java Java]====
====[http://rosettacode.org/mw/index.php?oldid=287744#Java Java]====
Line 1,466: Line 1,466:


Since Java uses interfaces and C# uses delegates, which are the only type that the C# compiler will coerce lambda expressions to, this code declares a <code>Functions</code> class for providing a means of converting CLR delegates to objects that implement the <code>Function</code> and <code>RecursiveFunction</code> interfaces.
Since Java uses interfaces and C# uses delegates, which are the only type that the C# compiler will coerce lambda expressions to, this code declares a <code>Functions</code> class for providing a means of converting CLR delegates to objects that implement the <code>Function</code> and <code>RecursiveFunction</code> interfaces.
<lang csharp>using System;
<syntaxhighlight lang="csharp">using System;


static class Program {
static class Program {
Line 1,514: Line 1,514:
Console.WriteLine("fac(10) = " + fac.apply(10));
Console.WriteLine("fac(10) = " + fac.apply(10));
}
}
}</lang>
}</syntaxhighlight>


'''"Idiomatic"'''
'''"Idiomatic"'''


For demonstrative purposes, to completely avoid using CLR delegates, lambda expressions can be replaced with explicit types that implement the functional interfaces. Closures are thus implemented by replacing all usages of the original local variable with a field of the type that represents the lambda expression; this process, called "hoisting" is actually how variable capturing is implemented by the C# compiler (for more information, see [https://blogs.msdn.microsoft.com/abhinaba/2005/10/18/c-anonymous-methods-are-not-closures/ this Microsoft blog post].
For demonstrative purposes, to completely avoid using CLR delegates, lambda expressions can be replaced with explicit types that implement the functional interfaces. Closures are thus implemented by replacing all usages of the original local variable with a field of the type that represents the lambda expression; this process, called "hoisting" is actually how variable capturing is implemented by the C# compiler (for more information, see [https://blogs.msdn.microsoft.com/abhinaba/2005/10/18/c-anonymous-methods-are-not-closures/ this Microsoft blog post].
<lang csharp>using System;
<syntaxhighlight lang="csharp">using System;


static class YCombinator {
static class YCombinator {
Line 1,609: Line 1,609:
Console.WriteLine("fac(10) = " + fac.apply(10));
Console.WriteLine("fac(10) = " + fac.apply(10));
}
}
}</lang>
}</syntaxhighlight>


'''C# 1.0'''
'''C# 1.0'''


To conclude this chain of decreasing reliance on language features, here is above code translated to C# 1.0. The largest change is the replacement of the generic interfaces with the results of manually substituting their type parameters.
To conclude this chain of decreasing reliance on language features, here is above code translated to C# 1.0. The largest change is the replacement of the generic interfaces with the results of manually substituting their type parameters.
<lang csharp>using System;
<syntaxhighlight lang="csharp">using System;


class Program {
class Program {
Line 1,710: Line 1,710:
Console.WriteLine("fac(10) = " + fac.apply(10));
Console.WriteLine("fac(10) = " + fac.apply(10));
}
}
}</lang>
}</syntaxhighlight>


'''Modified/varargs (the last implementation in the Java section)'''
'''Modified/varargs (the last implementation in the Java section)'''
Line 1,716: Line 1,716:
Since C# delegates cannot declare members, extension methods are used to simulate doing so.
Since C# delegates cannot declare members, extension methods are used to simulate doing so.


<lang csharp>using System;
<syntaxhighlight lang="csharp">using System;
using System.Collections.Generic;
using System.Collections.Generic;
using System.Linq;
using System.Linq;
Line 1,844: Line 1,844:
).ForAll(Console.WriteLine);
).ForAll(Console.WriteLine);
}
}
}</lang>
}</syntaxhighlight>


====[http://rosettacode.org/mw/index.php?oldid=287744#Swift Swift]====
====[http://rosettacode.org/mw/index.php?oldid=287744#Swift Swift]====
Line 1,852: Line 1,852:


The more idiomatic version doesn't look much different.
The more idiomatic version doesn't look much different.
<lang csharp>using System;
<syntaxhighlight lang="csharp">using System;


static class Program {
static class Program {
Line 1,872: Line 1,872:
Console.WriteLine($"fib(9) = {fib(9)}");
Console.WriteLine($"fib(9) = {fib(9)}");
}
}
}</lang>
}</syntaxhighlight>


Without recursive type:
Without recursive type:
<lang csharp> public static Func<A, B> Y<A, B>(Func<Func<A, B>, Func<A, B>> f) {
<syntaxhighlight lang="csharp"> public static Func<A, B> Y<A, B>(Func<Func<A, B>, Func<A, B>> f) {
Func<dynamic, Func<A, B>> r = z => { var w = (Func<dynamic, Func<A, B>>)z; return f(_0 => w(w)(_0)); };
Func<dynamic, Func<A, B>> r = z => { var w = (Func<dynamic, Func<A, B>>)z; return f(_0 => w(w)(_0)); };
return r(r);
return r(r);
}</lang>
}</syntaxhighlight>


Recursive:
Recursive:
<lang csharp> public static Func<In, Out> Y<In, Out>(Func<Func<In, Out>, Func<In, Out>> f) {
<syntaxhighlight lang="csharp"> public static Func<In, Out> Y<In, Out>(Func<Func<In, Out>, Func<In, Out>> f) {
return x => f(Y(f))(x);
return x => f(Y(f))(x);
}</lang>
}</syntaxhighlight>


=={{header|C++}}==
=={{header|C++}}==
Line 1,889: Line 1,889:
Known to work with GCC 4.7.2. Compile with
Known to work with GCC 4.7.2. Compile with
g++ --std=c++11 ycomb.cc
g++ --std=c++11 ycomb.cc
<lang cpp>#include <iostream>
<syntaxhighlight lang="cpp">#include <iostream>
#include <functional>
#include <functional>


Line 1,931: Line 1,931:
std::cout << "fac(10) = " << fac(10) << std::endl;
std::cout << "fac(10) = " << fac(10) << std::endl;
return 0;
return 0;
}</lang>
}</syntaxhighlight>
{{out}}
{{out}}


Line 1,942: Line 1,942:
A shorter version, taking advantage of generic lambdas. Known to work with GCC 5.2.0, but likely some earlier versions as well. Compile with
A shorter version, taking advantage of generic lambdas. Known to work with GCC 5.2.0, but likely some earlier versions as well. Compile with
g++ --std=c++14 ycomb.cc
g++ --std=c++14 ycomb.cc
<lang cpp>#include <iostream>
<syntaxhighlight lang="cpp">#include <iostream>
#include <functional>
#include <functional>
int main () {
int main () {
Line 1,962: Line 1,962:
std:: cout << fib (10) << '\n'
std:: cout << fib (10) << '\n'
<< fac (10) << '\n';
<< fac (10) << '\n';
}</lang>
}</syntaxhighlight>
{{out}}
{{out}}


Line 1,971: Line 1,971:


The usual version using recursion, disallowed by the task:
The usual version using recursion, disallowed by the task:
<lang cpp>template <typename A, typename B>
<syntaxhighlight lang="cpp">template <typename A, typename B>
std::function<B(A)> Y (std::function<std::function<B(A)>(std::function<B(A)>)> f) {
std::function<B(A)> Y (std::function<std::function<B(A)>(std::function<B(A)>)> f) {
return [f](A x) {
return [f](A x) {
return f(Y(f))(x);
return f(Y(f))(x);
};
};
}</lang>
}</syntaxhighlight>


Another version which is disallowed because a function passes itself, which is also a kind of recursion:
Another version which is disallowed because a function passes itself, which is also a kind of recursion:
<lang cpp>template <typename A, typename B>
<syntaxhighlight lang="cpp">template <typename A, typename B>
struct YFunctor {
struct YFunctor {
const std::function<std::function<B(A)>(std::function<B(A)>)> f;
const std::function<std::function<B(A)>(std::function<B(A)>)> f;
Line 1,991: Line 1,991:
std::function<B(A)> Y (std::function<std::function<B(A)>(std::function<B(A)>)> f) {
std::function<B(A)> Y (std::function<std::function<B(A)>(std::function<B(A)>)> f) {
return YFunctor<A,B>(f);
return YFunctor<A,B>(f);
}</lang>
}</syntaxhighlight>


=={{header|Ceylon}}==
=={{header|Ceylon}}==
Using a class for the recursive type:
Using a class for the recursive type:
<lang ceylon>Result(*Args) y1<Result,Args>(
<syntaxhighlight lang="ceylon">Result(*Args) y1<Result,Args>(
Result(*Args)(Result(*Args)) f)
Result(*Args)(Result(*Args)) f)
given Args satisfies Anything[] {
given Args satisfies Anything[] {
Line 2,016: Line 2,016:


print(factorialY1(10)); // 3628800
print(factorialY1(10)); // 3628800
print(fibY1(10)); // 110</lang>
print(fibY1(10)); // 110</syntaxhighlight>


Using Anything to erase the function type:
Using Anything to erase the function type:
<lang ceylon>Result(*Args) y2<Result,Args>(
<syntaxhighlight lang="ceylon">Result(*Args) y2<Result,Args>(
Result(*Args)(Result(*Args)) f)
Result(*Args)(Result(*Args)) f)
given Args satisfies Anything[] {
given Args satisfies Anything[] {
Line 2,029: Line 2,029:


return r(r);
return r(r);
}</lang>
}</syntaxhighlight>


Using recursion, this does not satisfy the task requirements, but is included here for illustrative purposes:
Using recursion, this does not satisfy the task requirements, but is included here for illustrative purposes:
<lang ceylon>Result(*Args) y3<Result, Args>(
<syntaxhighlight lang="ceylon">Result(*Args) y3<Result, Args>(
Result(*Args)(Result(*Args)) f)
Result(*Args)(Result(*Args)) f)
given Args satisfies Anything[]
given Args satisfies Anything[]
=> flatten((Args args) => f(y3(f))(*args));</lang>
=> flatten((Args args) => f(y3(f))(*args));</syntaxhighlight>


=={{header|Chapel}}==
=={{header|Chapel}}==
Line 2,042: Line 2,042:


{{works with|Chapel version 1.24.1}}
{{works with|Chapel version 1.24.1}}
<lang chapel>proc fixz(f) {
<syntaxhighlight lang="chapel">proc fixz(f) {
record InnerFunc {
record InnerFunc {
const xi;
const xi;
Line 2,077: Line 2,077:


writeln(facz(10));
writeln(facz(10));
writeln(fibz(10));</lang>
writeln(fibz(10));</syntaxhighlight>
{{out}}
{{out}}
<pre>3628800
<pre>3628800
Line 2,085: Line 2,085:


{{works with|Chapel version 1.24.1}}
{{works with|Chapel version 1.24.1}}
<lang chapel>// this is the longer version...
<syntaxhighlight lang="chapel">// this is the longer version...
/*
/*
proc fixy(f) {
proc fixy(f) {
Line 2,132: Line 2,132:


writeln(facy(10));
writeln(facy(10));
writeln(fibz(10));</lang>
writeln(fibz(10));</syntaxhighlight>
The output is the same as the above.
The output is the same as the above.


=={{header|Clojure}}==
=={{header|Clojure}}==
<lang lisp>(defn Y [f]
<syntaxhighlight lang="lisp">(defn Y [f]
((fn [x] (x x))
((fn [x] (x x))
(fn [x]
(fn [x]
Line 2,154: Line 2,154:
1 1
1 1
(+ (f (dec n))
(+ (f (dec n))
(f (dec (dec n))))))))</lang>
(f (dec (dec n))))))))</syntaxhighlight>


{{out}}
{{out}}
Line 2,164: Line 2,164:
<code>Y</code> can be written slightly more concisely via syntax sugar:
<code>Y</code> can be written slightly more concisely via syntax sugar:


<lang lisp>(defn Y [f]
<syntaxhighlight lang="lisp">(defn Y [f]
(#(% %) #(f (fn [& args] (apply (% %) args)))))</lang>
(#(% %) #(f (fn [& args] (apply (% %) args)))))</syntaxhighlight>


=={{header|CoffeeScript}}==
=={{header|CoffeeScript}}==
<lang coffeescript>Y = (f) -> g = f( (t...) -> g(t...) )</lang>
<syntaxhighlight lang="coffeescript">Y = (f) -> g = f( (t...) -> g(t...) )</syntaxhighlight>
or
or
<lang coffeescript>Y = (f) -> ((h)->h(h))((h)->f((t...)->h(h)(t...)))</lang>
<syntaxhighlight lang="coffeescript">Y = (f) -> ((h)->h(h))((h)->f((t...)->h(h)(t...)))</syntaxhighlight>
<lang coffeescript>fac = Y( (f) -> (n) -> if n > 1 then n * f(n-1) else 1 )
<syntaxhighlight lang="coffeescript">fac = Y( (f) -> (n) -> if n > 1 then n * f(n-1) else 1 )
fib = Y( (f) -> (n) -> if n > 1 then f(n-1) + f(n-2) else n )
fib = Y( (f) -> (n) -> if n > 1 then f(n-1) + f(n-2) else n )
</syntaxhighlight>
</lang>


=={{header|Common Lisp}}==
=={{header|Common Lisp}}==
<lang lisp>(defun Y (f)
<syntaxhighlight lang="lisp">(defun Y (f)
((lambda (g) (funcall g g))
((lambda (g) (funcall g g))
(lambda (g)
(lambda (g)
Line 2,204: Line 2,204:


? (mapcar #'fib '(1 2 3 4 5 6 7 8 9 10))
? (mapcar #'fib '(1 2 3 4 5 6 7 8 9 10))
(1 1 2 3 5 8 13 21 34 55)</lang>
(1 1 2 3 5 8 13 21 34 55)</syntaxhighlight>


=={{header|Crystal}}==
=={{header|Crystal}}==
Line 2,212: Line 2,212:
The following Crystal code implements the name-recursion Y-Combinator without assuming that functions are recursive (which in Crystal they actually are):
The following Crystal code implements the name-recursion Y-Combinator without assuming that functions are recursive (which in Crystal they actually are):


<lang crystal>require "big"
<syntaxhighlight lang="crystal">require "big"


struct RecursiveFunc(T) # a generic recursive function wrapper...
struct RecursiveFunc(T) # a generic recursive function wrapper...
Line 2,242: Line 2,242:


puts fac(10)
puts fac(10)
puts fib(11) # starts from 0 not 1!</lang>
puts fib(11) # starts from 0 not 1!</syntaxhighlight>


The "horrendously inefficient" massively repetitious implementations can be made much more efficient by changing the implementation for the two functions as follows:
The "horrendously inefficient" massively repetitious implementations can be made much more efficient by changing the implementation for the two functions as follows:


<lang crystal>def fac(x) # the more efficient tail recursive version...
<syntaxhighlight lang="crystal">def fac(x) # the more efficient tail recursive version...
facp = -> (fn : Proc(BigInt -> (Int32 -> BigInt))) {
facp = -> (fn : Proc(BigInt -> (Int32 -> BigInt))) {
-> (n : BigInt) { -> (i : Int32) {
-> (n : BigInt) { -> (i : Int32) {
Line 2,258: Line 2,258:
i < 2 ? f : fn.call.call(s).call(f + s).call(i - 1) } } } }
i < 2 ? f : fn.call.call(s).call(f + s).call(i - 1) } } } }
YCombo.new(fibp).fixy.call(BigInt.new).call(BigInt.new(1)).call(x)
YCombo.new(fibp).fixy.call(BigInt.new).call(BigInt.new(1)).call(x)
end</lang>
end</syntaxhighlight>


Finally, since Crystal function's/"def"'s can call themselves recursively, the implementation of the Y-Combinator can be changed to use this while still being "call by name" (not value/variable recursion) as follows; this uses the identical lambda "Proc"'s internally with just the application to the Y-Combinator changed:
Finally, since Crystal function's/"def"'s can call themselves recursively, the implementation of the Y-Combinator can be changed to use this while still being "call by name" (not value/variable recursion) as follows; this uses the identical lambda "Proc"'s internally with just the application to the Y-Combinator changed:


<lang crystal>def ycombo(f)
<syntaxhighlight lang="crystal">def ycombo(f)
f.call(-> { ycombo(f) })
f.call(-> { ycombo(f) })
end
end
Line 2,278: Line 2,278:
i < 2 ? f : fn.call.call(s).call(f + s).call(i - 1) } } } }
i < 2 ? f : fn.call.call(s).call(f + s).call(i - 1) } } } }
ycombo(fibp).call(BigInt.new).call(BigInt.new(1)).call(x)
ycombo(fibp).call(BigInt.new).call(BigInt.new(1)).call(x)
end</lang>
end</syntaxhighlight>


All versions produce the same output:
All versions produce the same output:
Line 2,287: Line 2,287:
=={{header|D}}==
=={{header|D}}==
A stateless generic Y combinator:
A stateless generic Y combinator:
<lang d>import std.stdio, std.traits, std.algorithm, std.range;
<syntaxhighlight lang="d">import std.stdio, std.traits, std.algorithm, std.range;


auto Y(S, T...)(S delegate(T) delegate(S delegate(T)) f) {
auto Y(S, T...)(S delegate(T) delegate(S delegate(T)) f) {
Line 2,311: Line 2,311:
writeln("factorial: ", 10.iota.map!factorial);
writeln("factorial: ", 10.iota.map!factorial);
writeln("ackermann(3, 5): ", ackermann(3, 5));
writeln("ackermann(3, 5): ", ackermann(3, 5));
}</lang>
}</syntaxhighlight>
{{out}}
{{out}}
<pre>factorial: [1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880]
<pre>factorial: [1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880]
Line 2,321: Line 2,321:
{{trans|C++}}
{{trans|C++}}
(The translation is not literal; e.g. the function argument type is left unspecified to increase generality.)
(The translation is not literal; e.g. the function argument type is left unspecified to increase generality.)
<lang delphi>program Y;
<syntaxhighlight lang="delphi">program Y;


{$APPTYPE CONSOLE}
{$APPTYPE CONSOLE}
Line 2,387: Line 2,387:
Writeln ('Fib(10) = ', Fib (10));
Writeln ('Fib(10) = ', Fib (10));
Writeln ('Fac(10) = ', Fac (10));
Writeln ('Fac(10) = ', Fac (10));
end.</lang>
end.</syntaxhighlight>


=={{header|Dhall}}==
=={{header|Dhall}}==
Line 2,395: Line 2,395:
Here's an example using Natural/Fold to define recursive definitions of fibonacci and factorial:
Here's an example using Natural/Fold to define recursive definitions of fibonacci and factorial:


<lang Dhall>let const
<syntaxhighlight lang="dhall">let const
: ∀(b : Type) → ∀(a : Type) → a → b → a
: ∀(b : Type) → ∀(a : Type) → a → b → a
= λ(r : Type) → λ(a : Type) → λ(x : a) → λ(y : r) → x
= λ(r : Type) → λ(a : Type) → λ(x : a) → λ(y : r) → x
Line 2,439: Line 2,439:
n
n


in [fac 50, fib 50]</lang>
in [fac 50, fib 50]</syntaxhighlight>


The above dhall file gets rendered down to:
The above dhall file gets rendered down to:


<lang Dhall>[ 30414093201713378043612608166064768844377641568960512000000000000
<syntaxhighlight lang="dhall">[ 30414093201713378043612608166064768844377641568960512000000000000
, 12586269025
, 12586269025
]</lang>
]</syntaxhighlight>


=={{header|Déjà Vu}}==
=={{header|Déjà Vu}}==
{{trans|Python}}
{{trans|Python}}
<lang dejavu>Y f:
<syntaxhighlight lang="dejavu">Y f:
labda y:
labda y:
labda:
labda:
Line 2,475: Line 2,475:


!. fac 6
!. fac 6
!. fib 6</lang>
!. fib 6</syntaxhighlight>
{{out}}
{{out}}
<pre>720
<pre>720
Line 2,482: Line 2,482:
=={{header|E}}==
=={{header|E}}==
{{trans|Python}}
{{trans|Python}}
<lang e>def y := fn f { fn x { x(x) }(fn y { f(fn a { y(y)(a) }) }) }
<syntaxhighlight lang="e">def y := fn f { fn x { x(x) }(fn y { f(fn a { y(y)(a) }) }) }
def fac := fn f { fn n { if (n<2) {1} else { n*f(n-1) } }}
def fac := fn f { fn n { if (n<2) {1} else { n*f(n-1) } }}
def fib := fn f { fn n { if (n == 0) {0} else if (n == 1) {1} else { f(n-1) + f(n-2) } }}</lang>
def fib := fn f { fn n { if (n == 0) {0} else if (n == 1) {1} else { f(n-1) + f(n-2) } }}</syntaxhighlight>


<lang e>? pragma.enable("accumulator")
<syntaxhighlight lang="e">? pragma.enable("accumulator")
? accum [] for i in 0..!10 { _.with(y(fac)(i)) }
? accum [] for i in 0..!10 { _.with(y(fac)(i)) }
[1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880]
[1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880]


? accum [] for i in 0..!10 { _.with(y(fib)(i)) }
? accum [] for i in 0..!10 { _.with(y(fib)(i)) }
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34]</lang>
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34]</syntaxhighlight>


=={{header|EchoLisp}}==
=={{header|EchoLisp}}==
<lang scheme>
<syntaxhighlight lang="scheme">
;; Ref : http://www.ece.uc.edu/~franco/C511/html/Scheme/ycomb.html
;; Ref : http://www.ece.uc.edu/~franco/C511/html/Scheme/ycomb.html


Line 2,518: Line 2,518:
(fact 10)
(fact 10)
→ 3628800
→ 3628800
</syntaxhighlight>
</lang>


=={{header|Eero}}==
=={{header|Eero}}==
Translated from Objective-C example on this page.
Translated from Objective-C example on this page.
<lang objc>#import <Foundation/Foundation.h>
<syntaxhighlight lang="objc">#import <Foundation/Foundation.h>


typedef int (^Func)(int)
typedef int (^Func)(int)
Line 2,550: Line 2,550:
Log('fac(10) = %d', fac(10))
Log('fac(10) = %d', fac(10))


return 0</lang>
return 0</syntaxhighlight>


=={{header|Ela}}==
=={{header|Ela}}==
<lang ela>fix = \f -> (\x -> & f (x x)) (\x -> & f (x x))
<syntaxhighlight lang="ela">fix = \f -> (\x -> & f (x x)) (\x -> & f (x x))


fac _ 0 = 1
fac _ 0 = 1
Line 2,562: Line 2,562:
fib f n = f (n - 1) + f (n - 2)
fib f n = f (n - 1) + f (n - 2)


(fix fac 12, fix fib 12)</lang>
(fix fac 12, fix fib 12)</syntaxhighlight>


{{out}}
{{out}}
Line 2,570: Line 2,570:
{{trans|Smalltalk}}
{{trans|Smalltalk}}
ELENA 4.x :
ELENA 4.x :
<lang elena>import extensions;
<syntaxhighlight lang="elena">import extensions;
singleton YCombinator
singleton YCombinator
Line 2,585: Line 2,585:
console.printLine("fib(10)=",fib(10));
console.printLine("fib(10)=",fib(10));
console.printLine("fact(10)=",fact(10));
console.printLine("fact(10)=",fact(10));
}</lang>
}</syntaxhighlight>
{{out}}
{{out}}
<pre>
<pre>
Line 2,594: Line 2,594:
=={{header|Elixir}}==
=={{header|Elixir}}==
{{trans|Python}}
{{trans|Python}}
<lang elixir>
<syntaxhighlight lang="elixir">
iex(1)> yc = fn f -> (fn x -> x.(x) end).(fn y -> f.(fn arg -> y.(y).(arg) end) end) end
iex(1)> yc = fn f -> (fn x -> x.(x) end).(fn y -> f.(fn arg -> y.(y).(arg) end) end) end
#Function<6.90072148/1 in :erl_eval.expr/5>
#Function<6.90072148/1 in :erl_eval.expr/5>
Line 2,605: Line 2,605:
iex(5)> for i <- 0..9, do: yc.(fib).(i)
iex(5)> for i <- 0..9, do: yc.(fib).(i)
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34]
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34]
</syntaxhighlight>
</lang>


=={{header|Elm}}==
=={{header|Elm}}==
Line 2,613: Line 2,613:
Note: the Fibonacci sequence is defined to start with zero or one, with the first exactly the same but with a zero prepended; these Fibonacci calculations use the second definition.
Note: the Fibonacci sequence is defined to start with zero or one, with the first exactly the same but with a zero prepended; these Fibonacci calculations use the second definition.


<lang elm>module Main exposing ( main )
<syntaxhighlight lang="elm">module Main exposing ( main )


import Html exposing ( Html, text )
import Html exposing ( Html, text )
Line 2,687: Line 2,687:
++ " " ++ String.fromInt (facy 10) ++ " " ++ String.fromInt (fiby 10)
++ " " ++ String.fromInt (facy 10) ++ " " ++ String.fromInt (fiby 10)
++ " " ++ nCISs2String 20 (fibs())
++ " " ++ nCISs2String 20 (fibs())
|> text</lang>
|> text</syntaxhighlight>
{{out}}
{{out}}
<pre>3628800 55 3628800 55 ( 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181 6765 )</pre>
<pre>3628800 55 3628800 55 ( 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181 6765 )</pre>


=={{header|Erlang}}==
=={{header|Erlang}}==
<lang erlang>Y = fun(M) -> (fun(X) -> X(X) end)(fun (F) -> M(fun(A) -> (F(F))(A) end) end) end.
<syntaxhighlight lang="erlang">Y = fun(M) -> (fun(X) -> X(X) end)(fun (F) -> M(fun(A) -> (F(F))(A) end) end) end.


Fac = fun (F) ->
Fac = fun (F) ->
Line 2,706: Line 2,706:
end.
end.
(Y(Fac))(5). %% 120
(Y(Fac))(5). %% 120
(Y(Fib))(8). %% 21</lang>
(Y(Fib))(8). %% 21</syntaxhighlight>


=={{header|F Sharp|F#}}==
=={{header|F Sharp|F#}}==
<lang fsharp>type 'a mu = Roll of ('a mu -> 'a) // ' fixes ease syntax colouring confusion with
<syntaxhighlight lang="fsharp">type 'a mu = Roll of ('a mu -> 'a) // ' fixes ease syntax colouring confusion with
let unroll (Roll x) = x
let unroll (Roll x) = x
Line 2,743: Line 2,743:
fac 10 |> printfn "%A" // prints 3628800
fac 10 |> printfn "%A" // prints 3628800
fib 10 |> printfn "%A" // prints 55
fib 10 |> printfn "%A" // prints 55
0 // return an integer exit code</lang>
0 // return an integer exit code</syntaxhighlight>
{{output}}
{{output}}
<pre>3628800
<pre>3628800
Line 2,752: Line 2,752:
Also note that the above isn't the true fix point Y-combinator which would race without the beta conversion to the Z-combinator with the included `a` argument; the Z-combinator can't be used in all cases that require a true Y-combinator such as in the formation of deferred execution sequences in the last example, as follows:
Also note that the above isn't the true fix point Y-combinator which would race without the beta conversion to the Z-combinator with the included `a` argument; the Z-combinator can't be used in all cases that require a true Y-combinator such as in the formation of deferred execution sequences in the last example, as follows:


<lang fsharp>// same as previous...
<syntaxhighlight lang="fsharp">// same as previous...
type 'a mu = Roll of ('a mu -> 'a) // ' fixes ease syntax colouring confusion with
type 'a mu = Roll of ('a mu -> 'a) // ' fixes ease syntax colouring confusion with
Line 2,791: Line 2,791:
fibs() |> Seq.take 20 |> Seq.iter (printf "%A ")
fibs() |> Seq.take 20 |> Seq.iter (printf "%A ")
printfn ""
printfn ""
0 // return an integer exit code</lang>
0 // return an integer exit code</syntaxhighlight>
{{output}}
{{output}}
<pre>3628800
<pre>3628800
Line 2,798: Line 2,798:


The above would be useful if F# did not have recursive functions (functions that can call themselves in their own definition), but as for most modern languages, F# does have function recursion by the use of the `rec` keyword before the function name, thus the above `fac` and `fib` functions can be written much more simply (and to run faster using tail recursion) with a recursion definition for the `fix` Y-combinator as follows, with a simple injected deferred execution to prevent race:
The above would be useful if F# did not have recursive functions (functions that can call themselves in their own definition), but as for most modern languages, F# does have function recursion by the use of the `rec` keyword before the function name, thus the above `fac` and `fib` functions can be written much more simply (and to run faster using tail recursion) with a recursion definition for the `fix` Y-combinator as follows, with a simple injected deferred execution to prevent race:
<lang fsharp>let rec fix f = f <| fun() -> fix f
<syntaxhighlight lang="fsharp">let rec fix f = f <| fun() -> fix f
// val fix : f:((unit -> 'a) -> 'a) -> 'a
// val fix : f:((unit -> 'a) -> 'a) -> 'a


// the application of this true Y-combinator is the same as for the above non function recursive version.</lang>
// the application of this true Y-combinator is the same as for the above non function recursive version.</syntaxhighlight>


Using the Y-combinator (or Z-combinator) as expressed here is pointless as in unnecessary and makes the code slower due to the extra function calls through the call stack, with the first non-function recursive implementation even slower than the second function recursion one; a non Y-combinator version can use function recursion with tail call optimization to simplify looping for about 100 times the speed in the actual loop overhead; thus, this is primarily an intellectual exercise.
Using the Y-combinator (or Z-combinator) as expressed here is pointless as in unnecessary and makes the code slower due to the extra function calls through the call stack, with the first non-function recursive implementation even slower than the second function recursion one; a non Y-combinator version can use function recursion with tail call optimization to simplify looping for about 100 times the speed in the actual loop overhead; thus, this is primarily an intellectual exercise.
Line 2,809: Line 2,809:
=={{header|Factor}}==
=={{header|Factor}}==
In rosettacode/Y.factor
In rosettacode/Y.factor
<lang factor>USING: fry kernel math ;
<syntaxhighlight lang="factor">USING: fry kernel math ;
IN: rosettacode.Y
IN: rosettacode.Y
: Y ( quot -- quot )
: Y ( quot -- quot )
Line 2,818: Line 2,818:


: almost-fib ( quot -- quot )
: almost-fib ( quot -- quot )
'[ dup 2 >= [ 1 2 [ - @ ] bi-curry@ bi + ] when ] ;</lang>
'[ dup 2 >= [ 1 2 [ - @ ] bi-curry@ bi + ] when ] ;</syntaxhighlight>
In rosettacode/Y-tests.factor
In rosettacode/Y-tests.factor
<lang factor>USING: kernel tools.test rosettacode.Y ;
<syntaxhighlight lang="factor">USING: kernel tools.test rosettacode.Y ;
IN: rosettacode.Y.tests
IN: rosettacode.Y.tests


[ 120 ] [ 5 [ almost-fac ] Y call ] unit-test
[ 120 ] [ 5 [ almost-fac ] Y call ] unit-test
[ 8 ] [ 6 [ almost-fib ] Y call ] unit-test</lang>
[ 8 ] [ 6 [ almost-fib ] Y call ] unit-test</syntaxhighlight>
running the tests :
running the tests :
<pre> ( scratchpad - auto ) "rosettacode.Y" test
<pre> ( scratchpad - auto ) "rosettacode.Y" test
Line 2,832: Line 2,832:


=={{header|Falcon}}==
=={{header|Falcon}}==
<syntaxhighlight lang="falcon">
<lang Falcon>
Y = { f => {x=> {n => f(x(x))(n)}} ({x=> {n => f(x(x))(n)}}) }
Y = { f => {x=> {n => f(x(x))(n)}} ({x=> {n => f(x(x))(n)}}) }
facStep = { f => {x => x < 1 ? 1 : x*f(x-1) }}
facStep = { f => {x => x < 1 ? 1 : x*f(x-1) }}
Line 2,842: Line 2,842:
> "Factorial 10: ", YFac(10)
> "Factorial 10: ", YFac(10)
> "Fibonacci 10: ", YFib(10)
> "Fibonacci 10: ", YFib(10)
</syntaxhighlight>
</lang>


=={{header|Forth}}==
=={{header|Forth}}==
<lang Forth>\ Address of an xt.
<syntaxhighlight lang="forth">\ Address of an xt.
variable 'xt
variable 'xt
\ Make room for an xt.
\ Make room for an xt.
Line 2,856: Line 2,856:
: y, ( xt1 -- xt2 ) >r :noname @xt, r> compile, postpone ; ;
: y, ( xt1 -- xt2 ) >r :noname @xt, r> compile, postpone ; ;
\ Make a new instance of the Y combinator.
\ Make a new instance of the Y combinator.
: y ( xt1 -- xt2 ) xt, y, dup !xt ;</lang>
: y ( xt1 -- xt2 ) xt, y, dup !xt ;</syntaxhighlight>


Samples:
Samples:
<lang Forth>\ Factorial
<syntaxhighlight lang="forth">\ Factorial
10 :noname ( u1 xt -- u2 ) over ?dup if 1- swap execute * else 2drop 1 then ;
10 :noname ( u1 xt -- u2 ) over ?dup if 1- swap execute * else 2drop 1 then ;
y execute . 3628800 ok
y execute . 3628800 ok
Line 2,866: Line 2,866:
10 :noname ( u1 xt -- u2 ) over 2 < if drop else >r 1- dup r@ execute swap 1- r> execute + then ;
10 :noname ( u1 xt -- u2 ) over 2 < if drop else >r 1- dup r@ execute swap 1- r> execute + then ;
y execute . 55 ok
y execute . 55 ok
</syntaxhighlight>
</lang>


=={{header|FreeBASIC}}==
=={{header|FreeBASIC}}==
FreeBASIC does not support nested functions, lambda expressions or functions inside nested types
FreeBASIC does not support nested functions, lambda expressions or functions inside nested types
<lang freebasic>Function Y(f As String) As String
<syntaxhighlight lang="freebasic">Function Y(f As String) As String
Y = f
Y = f
End Function
End Function
Line 2,906: Line 2,906:
test("fac")
test("fac")
test("fib")
test("fib")
Sleep</lang>
Sleep</syntaxhighlight>
{{out}}
{{out}}
<pre>fac: 1 2 6 24 120 720 5040 40320 362880 3628800
<pre>fac: 1 2 6 24 120 720 5040 40320 362880 3628800
Line 2,913: Line 2,913:


=={{header|GAP}}==
=={{header|GAP}}==
<lang gap>Y := function(f)
<syntaxhighlight lang="gap">Y := function(f)
local u;
local u;
u := x -> x(x);
u := x -> x(x);
Line 2,947: Line 2,947:


Y(fac)(8);
Y(fac)(8);
# 40320</lang>
# 40320</syntaxhighlight>


=={{header|Genyris}}==
=={{header|Genyris}}==
{{trans|Scheme}}
{{trans|Scheme}}
<lang genyris>def fac (f)
<syntaxhighlight lang="genyris">def fac (f)
function (n)
function (n)
if (equal? n 0) 1
if (equal? n 0) 1
Line 2,969: Line 2,969:


assertEqual ((Y fac) 5) 120
assertEqual ((Y fac) 5) 120
assertEqual ((Y fib) 8) 21</lang>
assertEqual ((Y fib) 8) 21</syntaxhighlight>


=={{header|Go}}==
=={{header|Go}}==
<lang go>package main
<syntaxhighlight lang="go">package main


import "fmt"
import "fmt"
Line 3,012: Line 3,012:
return f(x-1)+f(x-2)
return f(x-1)+f(x-2)
}
}
}</lang>
}</syntaxhighlight>
{{out}}
{{out}}
<pre>
<pre>
Line 3,020: Line 3,020:


The usual version using recursion, disallowed by the task:
The usual version using recursion, disallowed by the task:
<lang go>func Y(f FuncFunc) Func {
<syntaxhighlight lang="go">func Y(f FuncFunc) Func {
return func(x int) int {
return func(x int) int {
return f(Y(f))(x)
return f(Y(f))(x)
}
}
}</lang>
}</syntaxhighlight>


=={{header|Groovy}}==
=={{header|Groovy}}==
Here is the simplest (unary) form of applicative order Y:
Here is the simplest (unary) form of applicative order Y:
<lang groovy>def Y = { le -> ({ f -> f(f) })({ f -> le { x -> f(f)(x) } }) }
<syntaxhighlight lang="groovy">def Y = { le -> ({ f -> f(f) })({ f -> le { x -> f(f)(x) } }) }


def factorial = Y { fac ->
def factorial = Y { fac ->
Line 3,040: Line 3,040:
}
}


assert fib(10) == 55</lang>
assert fib(10) == 55</syntaxhighlight>
This version was translated from the one in ''The Little Schemer'' by Friedman and Felleisen. The use of the variable name ''le'' is due to the fact that the authors derive Y from an ordinary recursive '''''le'''ngth'' function.
This version was translated from the one in ''The Little Schemer'' by Friedman and Felleisen. The use of the variable name ''le'' is due to the fact that the authors derive Y from an ordinary recursive '''''le'''ngth'' function.


A variadic version of Y in Groovy looks like this:
A variadic version of Y in Groovy looks like this:
<lang groovy>def Y = { le -> ({ f -> f(f) })({ f -> le { Object[] args -> f(f)(*args) } }) }
<syntaxhighlight lang="groovy">def Y = { le -> ({ f -> f(f) })({ f -> le { Object[] args -> f(f)(*args) } }) }


def mul = Y { mulStar -> { a, b -> a ? b + mulStar(a - 1, b) : 0 } }
def mul = Y { mulStar -> { a, b -> a ? b + mulStar(a - 1, b) : 0 } }
Line 3,050: Line 3,050:
1.upto(10) {
1.upto(10) {
assert mul(it, 10) == it * 10
assert mul(it, 10) == it * 10
}</lang>
}</syntaxhighlight>


=={{header|Haskell}}==
=={{header|Haskell}}==
The obvious definition of the Y combinator <code>(\f-> (\x -> f (x x)) (\x-> f (x x)))</code> cannot be used in Haskell because it contains an infinite recursive type (<code>a = a -> b</code>). Defining a data type (Mu) allows this recursion to be broken.
The obvious definition of the Y combinator <code>(\f-> (\x -> f (x x)) (\x-> f (x x)))</code> cannot be used in Haskell because it contains an infinite recursive type (<code>a = a -> b</code>). Defining a data type (Mu) allows this recursion to be broken.
<lang haskell>newtype Mu a = Roll
<syntaxhighlight lang="haskell">newtype Mu a = Roll
{ unroll :: Mu a -> a }
{ unroll :: Mu a -> a }
Line 3,099: Line 3,099:
[ map fac [1 .. 20]
[ map fac [1 .. 20]
, take 20 $ fibs()
, take 20 $ fibs()
]</lang>
]</syntaxhighlight>


The usual version uses recursion on a binding, disallowed by the task, to define the <code>fix</code> itself; but the definitions produced by this <code>fix</code> does ''not'' use recursion on value bindings although it does use recursion when defining a function (not possible in all languages), so it can be viewed as a true Y-combinator too:
The usual version uses recursion on a binding, disallowed by the task, to define the <code>fix</code> itself; but the definitions produced by this <code>fix</code> does ''not'' use recursion on value bindings although it does use recursion when defining a function (not possible in all languages), so it can be viewed as a true Y-combinator too:


<lang haskell>-- note that this version of fix uses function recursion in its own definition;
<syntaxhighlight lang="haskell">-- note that this version of fix uses function recursion in its own definition;
-- thus its use just means that the recursion has been "pulled" into the "fix" function,
-- thus its use just means that the recursion has been "pulled" into the "fix" function,
-- instead of the function that uses it...
-- instead of the function that uses it...
Line 3,150: Line 3,150:
, map fib [1 .. 20]
, map fib [1 .. 20]
, take 20 fibs()
, take 20 fibs()
]</lang>
]</syntaxhighlight>


Now just because something is possible using the Y-combinator doesn't mean that it is practical: the above implementations can't compute much past the 1000th number in the Fibonacci list sequence and is quite slow at doing so; using direct function recursive routines compute about 100 times faster and don't hang for large ranges, nor give problems compiling as the first version does (GHC version 8.4.3 at -O1 optimization level).
Now just because something is possible using the Y-combinator doesn't mean that it is practical: the above implementations can't compute much past the 1000th number in the Fibonacci list sequence and is quite slow at doing so; using direct function recursive routines compute about 100 times faster and don't hang for large ranges, nor give problems compiling as the first version does (GHC version 8.4.3 at -O1 optimization level).
Line 3,161: Line 3,161:
===Non-tacit version===
===Non-tacit version===
Unfortunately, in principle, J functions cannot take functions of the same type as arguments. In other words, verbs (functions) cannot take verbs, and adverbs or conjunctions (higher-order functions) cannot take adverbs or conjunctions. This implementation uses the body, a literal (string), of an explicit adverb (a higher-order function with a left argument) as the argument for Y, to represent the adverb for which the product of Y is a fixed-point verb; Y itself is also an adverb.
Unfortunately, in principle, J functions cannot take functions of the same type as arguments. In other words, verbs (functions) cannot take verbs, and adverbs or conjunctions (higher-order functions) cannot take adverbs or conjunctions. This implementation uses the body, a literal (string), of an explicit adverb (a higher-order function with a left argument) as the argument for Y, to represent the adverb for which the product of Y is a fixed-point verb; Y itself is also an adverb.
<lang j>Y=. '('':''<@;(1;~":0)<@;<@((":0)&;))'(2 : 0 '')
<syntaxhighlight lang="j">Y=. '('':''<@;(1;~":0)<@;<@((":0)&;))'(2 : 0 '')
(1 : (m,'u'))(1 : (m,'''u u`:6('',(5!:5<''u''),'')`:6 y'''))(1 :'u u`:6')
(1 : (m,'u'))(1 : (m,'''u u`:6('',(5!:5<''u''),'')`:6 y'''))(1 :'u u`:6')
)
)
</syntaxhighlight>
</lang>
This Y combinator follows the standard method: it produces a fixed-point which reproduces and transforms itself anonymously according to the adverb represented by Y's argument. All names (variables) refer to arguments of the enclosing adverbs and there are no assignments.
This Y combinator follows the standard method: it produces a fixed-point which reproduces and transforms itself anonymously according to the adverb represented by Y's argument. All names (variables) refer to arguments of the enclosing adverbs and there are no assignments.


The factorial and Fibonacci examples follow:
The factorial and Fibonacci examples follow:
<lang j> 'if. * y do. y * u <: y else. 1 end.' Y 10 NB. Factorial
<syntaxhighlight lang="j"> 'if. * y do. y * u <: y else. 1 end.' Y 10 NB. Factorial
3628800
3628800
'(u@:<:@:<: + u@:<:)^:(1 < ])' Y 10 NB. Fibonacci
'(u@:<:@:<: + u@:<:)^:(1 < ])' Y 10 NB. Fibonacci
55</lang>
55</syntaxhighlight>
The names u, x, and y are J's standard names for arguments; the name y represents the argument of u and the name u represents the verb argument of the adverb for which Y produces a fixed-point. Any verb can also be expressed tacitly, without any reference to its argument(s), as in the Fibonacci example.
The names u, x, and y are J's standard names for arguments; the name y represents the argument of u and the name u represents the verb argument of the adverb for which Y produces a fixed-point. Any verb can also be expressed tacitly, without any reference to its argument(s), as in the Fibonacci example.


A structured derivation of a Y with states follows (the stateless version can be produced by replacing all the names by its referents):
A structured derivation of a Y with states follows (the stateless version can be produced by replacing all the names by its referents):
<lang j> arb=. ':'<@;(1;~":0)<@;<@((":0)&;) NB. AR of an explicit adverb from its body
<syntaxhighlight lang="j"> arb=. ':'<@;(1;~":0)<@;<@((":0)&;) NB. AR of an explicit adverb from its body
ara=. 1 :'arb u' NB. The verb arb as an adverb
ara=. 1 :'arb u' NB. The verb arb as an adverb
Line 3,181: Line 3,181:
gab=. 1 :'u u`:6' NB. The AR of the adverb and the adverb itself as a train
gab=. 1 :'u u`:6' NB. The AR of the adverb and the adverb itself as a train
Y=. ara srt gab NB. Train of adverbs</lang>
Y=. ara srt gab NB. Train of adverbs</syntaxhighlight>
The adverb Y, apart from using a representation as Y's argument, satisfies the task's requirements. However, it only works for monadic verbs (functions with a right argument). J's verbs can also be dyadic (functions with a left and right arguments) and ambivalent (almost all J's primitive verbs are ambivalent; for example - can be used as in - 1 and 2 - 1). The following adverb (XY) implements anonymous recursion of monadic, dyadic, and ambivalent verbs (the name x represents the left argument of u),
The adverb Y, apart from using a representation as Y's argument, satisfies the task's requirements. However, it only works for monadic verbs (functions with a right argument). J's verbs can also be dyadic (functions with a left and right arguments) and ambivalent (almost all J's primitive verbs are ambivalent; for example - can be used as in - 1 and 2 - 1). The following adverb (XY) implements anonymous recursion of monadic, dyadic, and ambivalent verbs (the name x represents the left argument of u),
<lang j>XY=. (1 :'('':''<@;(1;~":0)<@;<@((":0)&;))u')(1 :'('':''<@;(1;~":0)<@;<@((":0)&;))((''u u`:6('',(5!:5<''u''),'')`:6 y''),(10{a.),'':'',(10{a.),''x(u u`:6('',(5!:5<''u''),'')`:6)y'')')(1 :'u u`:6')</lang>
<syntaxhighlight lang="j">XY=. (1 :'('':''<@;(1;~":0)<@;<@((":0)&;))u')(1 :'('':''<@;(1;~":0)<@;<@((":0)&;))((''u u`:6('',(5!:5<''u''),'')`:6 y''),(10{a.),'':'',(10{a.),''x(u u`:6('',(5!:5<''u''),'')`:6)y'')')(1 :'u u`:6')</syntaxhighlight>
The following are examples of anonymous dyadic and ambivalent recursions,
The following are examples of anonymous dyadic and ambivalent recursions,
<lang j> 1 2 3 '([:`(>:@:])`(<:@:[ u 1:)`(<:@[ u [ u <:@:])@.(#.@,&*))'XY"0/ 1 2 3 4 5 NB. Ackermann function...
<syntaxhighlight lang="j"> 1 2 3 '([:`(>:@:])`(<:@:[ u 1:)`(<:@[ u [ u <:@:])@.(#.@,&*))'XY"0/ 1 2 3 4 5 NB. Ackermann function...
3 4 5 6 7
3 4 5 6 7
5 7 9 11 13
5 7 9 11 13
Line 3,198: Line 3,198:
8 11 20 41 86 179 368
8 11 20 41 86 179 368
NB. OEIS A097813 - main diagonal
NB. OEIS A097813 - main diagonal
NB. OEIS A050488 = A097813 - 1 - adyacent upper off-diagonal</lang>
NB. OEIS A050488 = A097813 - 1 - adyacent upper off-diagonal</syntaxhighlight>


J supports directly anonymous tacit recursion via the verb $: and for tacit recursions, XY is equivalent to the adverb,
J supports directly anonymous tacit recursion via the verb $: and for tacit recursions, XY is equivalent to the adverb,
<lang j>YX=. (1 :'('':''<@;(1;~":0)<@;<@((":0)&;))u')($:`)(`:6)</lang>
<syntaxhighlight lang="j">YX=. (1 :'('':''<@;(1;~":0)<@;<@((":0)&;))u')($:`)(`:6)</syntaxhighlight>


===Tacit version===
===Tacit version===
The Y combinator can be implemented indirectly using, for example, the linear representations of verbs (Y becomes a wrapper which takes an ad hoc verb as an argument and serializes it; the underlying self-referring system interprets the serialized representation of a verb as the corresponding verb):
The Y combinator can be implemented indirectly using, for example, the linear representations of verbs (Y becomes a wrapper which takes an ad hoc verb as an argument and serializes it; the underlying self-referring system interprets the serialized representation of a verb as the corresponding verb):
<lang j>Y=. ((((&>)/)((((^:_1)b.)(`(<'0';_1)))(`:6)))(&([ 128!:2 ,&<)))</lang>
<syntaxhighlight lang="j">Y=. ((((&>)/)((((^:_1)b.)(`(<'0';_1)))(`:6)))(&([ 128!:2 ,&<)))</syntaxhighlight>
The factorial and Fibonacci examples:
The factorial and Fibonacci examples:
<lang j> u=. [ NB. Function (left)
<syntaxhighlight lang="j"> u=. [ NB. Function (left)
n=. ] NB. Argument (right)
n=. ] NB. Argument (right)
sr=. [ apply f. ,&< NB. Self referring
sr=. [ apply f. ,&< NB. Self referring
Line 3,217: Line 3,217:
Fib=. ((u sr n - 2:) + u sr n - 1:) ^: (1 < n)
Fib=. ((u sr n - 2:) + u sr n - 1:) ^: (1 < n)
Fib f. Y 10
Fib f. Y 10
55</lang>
55</syntaxhighlight>
The stateless functions are shown next (the f. adverb replaces all embedded names by its referents):
The stateless functions are shown next (the f. adverb replaces all embedded names by its referents):
<lang j> fac f. Y NB. Factorial...
<syntaxhighlight lang="j"> fac f. Y NB. Factorial...
'1:`(] * [ ([ 128!:2 ,&<) ] - 1:)@.(0 < ])&>/'&([ 128!:2 ,&<)
'1:`(] * [ ([ 128!:2 ,&<) ] - 1:)@.(0 < ])&>/'&([ 128!:2 ,&<)


Line 3,230: Line 3,230:


Fib f. NB. Fibonacci step...
Fib f. NB. Fibonacci step...
(([ ([ 128!:2 ,&<) ] - 2:) + [ ([ 128!:2 ,&<) ] - 1:)^:(1 < ])</lang>
(([ ([ 128!:2 ,&<) ] - 2:) + [ ([ 128!:2 ,&<) ] - 1:)^:(1 < ])</syntaxhighlight>
A structured derivation of Y follows:
A structured derivation of Y follows:
<lang j> sr=. [ apply f.,&< NB. Self referring
<syntaxhighlight lang="j"> sr=. [ apply f.,&< NB. Self referring
lv=. (((^:_1)b.)(`(<'0';_1)))(`:6) NB. Linear representation of a verb argument
lv=. (((^:_1)b.)(`(<'0';_1)))(`:6) NB. Linear representation of a verb argument
Y=. (&>)/lv(&sr) NB. Y with embedded states
Y=. (&>)/lv(&sr) NB. Y with embedded states
Y=. 'Y'f. NB. Fixing it...
Y=. 'Y'f. NB. Fixing it...
Y NB. ... To make it stateless (i.e., a combinator)
Y NB. ... To make it stateless (i.e., a combinator)
((((&>)/)((((^:_1)b.)(`_1))(`:6)))(&([ 128!:2 ,&<)))</lang>
((((&>)/)((((^:_1)b.)(`_1))(`:6)))(&([ 128!:2 ,&<)))</syntaxhighlight>


===Explicit alternate implementation===
===Explicit alternate implementation===
Line 3,243: Line 3,243:
Another approach:
Another approach:


<lang j>Y=:1 :0
<syntaxhighlight lang="j">Y=:1 :0
f=. u Defer
f=. u Defer
(5!:1<'f') f y
(5!:1<'f') f y
Line 3,262: Line 3,262:
if. 2 > y do. y
if. 2 > y do. y
else. (x`:6 y-1) + x`:6 y-2 end.
else. (x`:6 y-1) + x`:6 y-2 end.
)</lang>
)</syntaxhighlight>


Example use:
Example use:


<lang J> almost_factorial Y 9
<syntaxhighlight lang="j"> almost_factorial Y 9
362880
362880
almost_fibonacci Y 9
almost_fibonacci Y 9
34
34
almost_fibonacci Y"0 i. 10
almost_fibonacci Y"0 i. 10
0 1 1 2 3 5 8 13 21 34</lang>
0 1 1 2 3 5 8 13 21 34</syntaxhighlight>


Or, if you would prefer to not have a dependency on the definition of Defer, an equivalent expression would be:
Or, if you would prefer to not have a dependency on the definition of Defer, an equivalent expression would be:


<lang J>Y=:2 :0(0 :0)
<syntaxhighlight lang="j">Y=:2 :0(0 :0)
NB. this block will be n in the second part
NB. this block will be n in the second part
:
:
Line 3,283: Line 3,283:
f=. u (1 :n)
f=. u (1 :n)
(5!:1<'f') f y
(5!:1<'f') f y
)</lang>
)</syntaxhighlight>


That said, if you think of association with a name as state (because in different contexts the association may not exist, or may be different) you might also want to remove that association in the context of the Y combinator.
That said, if you think of association with a name as state (because in different contexts the association may not exist, or may be different) you might also want to remove that association in the context of the Y combinator.
Line 3,289: Line 3,289:
For example:
For example:


<lang J> almost_factorial f. Y 10
<syntaxhighlight lang="j"> almost_factorial f. Y 10
3628800</lang>
3628800</syntaxhighlight>


=={{header|Java}}==
=={{header|Java}}==


{{works with|Java|8+}}
{{works with|Java|8+}}
<lang java5>import java.util.function.Function;
<syntaxhighlight lang="java5">import java.util.function.Function;


public interface YCombinator {
public interface YCombinator {
Line 3,319: Line 3,319:
System.out.println("fac(10) = " + fac.apply(10));
System.out.println("fac(10) = " + fac.apply(10));
}
}
}</lang>
}</syntaxhighlight>
{{out}}
{{out}}
<pre>
<pre>
Line 3,326: Line 3,326:
</pre>
</pre>
The usual version using recursion, disallowed by the task:
The usual version using recursion, disallowed by the task:
<lang java5> public static <A,B> Function<A,B> Y(Function<Function<A,B>, Function<A,B>> f) {
<syntaxhighlight lang="java5"> public static <A,B> Function<A,B> Y(Function<Function<A,B>, Function<A,B>> f) {
return x -> f.apply(Y(f)).apply(x);
return x -> f.apply(Y(f)).apply(x);
}</lang>
}</syntaxhighlight>


Another version which is disallowed because a function passes itself, which is also a kind of recursion:
Another version which is disallowed because a function passes itself, which is also a kind of recursion:
<lang java5> public static <A,B> Function<A,B> Y(Function<Function<A,B>, Function<A,B>> f) {
<syntaxhighlight lang="java5"> public static <A,B> Function<A,B> Y(Function<Function<A,B>, Function<A,B>> f) {
return new Function<A,B>() {
return new Function<A,B>() {
public B apply(A x) {
public B apply(A x) {
Line 3,337: Line 3,337:
}
}
};
};
}</lang>
}</syntaxhighlight>


{{works with|Java|pre-8}}
{{works with|Java|pre-8}}
We define a generic function interface like Java 8's <code>Function</code>.
We define a generic function interface like Java 8's <code>Function</code>.
<lang java5>interface Function<A, B> {
<syntaxhighlight lang="java5">interface Function<A, B> {
public B call(A x);
public B call(A x);
}
}
Line 3,393: Line 3,393:
System.out.println("fac(10) = " + fac.call(10));
System.out.println("fac(10) = " + fac.call(10));
}
}
}</lang>
}</syntaxhighlight>


The following code modifies the Function interface such that multiple parameters (via varargs) are supported, simplifies the y function considerably, and the [[Ackermann function#Java|Ackermann function]] has been included in this implementation (mostly because both [[Y combinator#D|D]] and [[Y combinator#PicoLisp|PicoLisp]] include it in their own implementations).
The following code modifies the Function interface such that multiple parameters (via varargs) are supported, simplifies the y function considerably, and the [[Ackermann function#Java|Ackermann function]] has been included in this implementation (mostly because both [[Y combinator#D|D]] and [[Y combinator#PicoLisp|PicoLisp]] include it in their own implementations).


<lang java5>import java.util.function.Function;
<syntaxhighlight lang="java5">import java.util.function.Function;


@FunctionalInterface
@FunctionalInterface
Line 3,404: Line 3,404:
return apply(this);
return apply(this);
}
}
}</lang>
}</syntaxhighlight>


<lang java5>import java.util.function.Function;
<syntaxhighlight lang="java5">import java.util.function.Function;
import java.util.function.UnaryOperator;
import java.util.function.UnaryOperator;


@FunctionalInterface
@FunctionalInterface
public interface FixedPoint<FUNCTION> extends Function<UnaryOperator<FUNCTION>, FUNCTION> {}</lang>
public interface FixedPoint<FUNCTION> extends Function<UnaryOperator<FUNCTION>, FUNCTION> {}</syntaxhighlight>


<lang java5>import java.util.Arrays;
<syntaxhighlight lang="java5">import java.util.Arrays;
import java.util.Optional;
import java.util.Optional;
import java.util.function.Function;
import java.util.function.Function;
Line 3,454: Line 3,454:
return inputs -> apply((INPUTS[]) Arrays.stream(inputs).parallel().map(transformer).toArray());
return inputs -> apply((INPUTS[]) Arrays.stream(inputs).parallel().map(transformer).toArray());
}
}
}</lang>
}</syntaxhighlight>


<lang java5>import java.math.BigDecimal;
<syntaxhighlight lang="java5">import java.math.BigDecimal;
import java.math.BigInteger;
import java.math.BigInteger;
import java.util.Arrays;
import java.util.Arrays;
Line 3,529: Line 3,529:
).forEach(System.out::println);
).forEach(System.out::println);
}
}
}</lang>
}</syntaxhighlight>


{{out}} (may depend on which function gets processed first):
{{out}} (may depend on which function gets processed first):
<lang>factorial[10] = 3628800
<syntaxhighlight lang="text">factorial[10] = 3628800
ackermann[3, 2] = 29
ackermann[3, 2] = 29
fibonacci[20] = 6765</lang>
fibonacci[20] = 6765</syntaxhighlight>


=={{header|JavaScript}}==
=={{header|JavaScript}}==
The standard version of the Y combinator does not use lexically bound local variables (or any local variables at all), which necessitates adding a wrapper function and some code duplication - the remaining locale variables are only there to make the relationship to the previous implementation more explicit:
The standard version of the Y combinator does not use lexically bound local variables (or any local variables at all), which necessitates adding a wrapper function and some code duplication - the remaining locale variables are only there to make the relationship to the previous implementation more explicit:
<lang javascript>function Y(f) {
<syntaxhighlight lang="javascript">function Y(f) {
var g = f((function(h) {
var g = f((function(h) {
return function() {
return function() {
Line 3,563: Line 3,563:
return n > 1 ? f(n - 1) + f(n - 2) : n;
return n > 1 ? f(n - 1) + f(n - 2) : n;
};
};
});</lang>
});</syntaxhighlight>
Changing the order of function application (i.e. the place where <code>f</code> gets called) and making use of the fact that we're generating a fixed-point, this can be reduced to
Changing the order of function application (i.e. the place where <code>f</code> gets called) and making use of the fact that we're generating a fixed-point, this can be reduced to
<lang javascript>function Y(f) {
<syntaxhighlight lang="javascript">function Y(f) {
return (function(h) {
return (function(h) {
return h(h);
return h(h);
Line 3,573: Line 3,573:
});
});
});
});
}</lang>
}</syntaxhighlight>
A functionally equivalent version using the implicit <code>this</code> parameter is also possible:
A functionally equivalent version using the implicit <code>this</code> parameter is also possible:
<lang javascript>function pseudoY(f) {
<syntaxhighlight lang="javascript">function pseudoY(f) {
return (function(h) {
return (function(h) {
return h(h);
return h(h);
Line 3,591: Line 3,591:
var fib = pseudoY(function(n) {
var fib = pseudoY(function(n) {
return n > 1 ? this(n - 1) + this(n - 2) : n;
return n > 1 ? this(n - 1) + this(n - 2) : n;
});</lang>
});</syntaxhighlight>
However, <code>pseudoY()</code> is not a fixed-point combinator.
However, <code>pseudoY()</code> is not a fixed-point combinator.


The usual version using recursion, disallowed by the task:
The usual version using recursion, disallowed by the task:
<lang javascript>function Y(f) {
<syntaxhighlight lang="javascript">function Y(f) {
return function() {
return function() {
return f(Y(f)).apply(this, arguments);
return f(Y(f)).apply(this, arguments);
};
};
}</lang>
}</syntaxhighlight>


Another version which is disallowed because it uses <code>arguments.callee</code> for a function to get itself recursively:
Another version which is disallowed because it uses <code>arguments.callee</code> for a function to get itself recursively:
<lang javascript>function Y(f) {
<syntaxhighlight lang="javascript">function Y(f) {
return function() {
return function() {
return f(arguments.callee).apply(this, arguments);
return f(arguments.callee).apply(this, arguments);
};
};
}</lang>
}</syntaxhighlight>
===ECMAScript 2015 (ES6) variants===
===ECMAScript 2015 (ES6) variants===
Since ECMAScript 2015 (ES6) just reached final draft, there are new ways to encode the applicative order Y combinator.
Since ECMAScript 2015 (ES6) just reached final draft, there are new ways to encode the applicative order Y combinator.
These use the new fat arrow function expression syntax, and are made to allow functions of more than one argument through the use of new rest parameters syntax and the corresponding new spread operator syntax. Also showcases new default parameter value syntax:
These use the new fat arrow function expression syntax, and are made to allow functions of more than one argument through the use of new rest parameters syntax and the corresponding new spread operator syntax. Also showcases new default parameter value syntax:
<lang javascript>let
<syntaxhighlight lang="javascript">let
Y= // Except for the η-abstraction necessary for applicative order languages, this is the formal Y combinator.
Y= // Except for the η-abstraction necessary for applicative order languages, this is the formal Y combinator.
f=>((g=>(f((...x)=>g(g)(...x))))
f=>((g=>(f((...x)=>g(g)(...x))))
Line 3,629: Line 3,629:
fact=>(n,m=1)=>n<2?m:fact(n-1,n*m);
fact=>(n,m=1)=>n<2?m:fact(n-1,n*m);
tailfact= // Tail call version of factorial function
tailfact= // Tail call version of factorial function
Y(opentailfact);</lang>
Y(opentailfact);</syntaxhighlight>
ECMAScript 2015 (ES6) also permits a really compact polyvariadic variant for mutually recursive functions:
ECMAScript 2015 (ES6) also permits a really compact polyvariadic variant for mutually recursive functions:
<lang javascript>let
<syntaxhighlight lang="javascript">let
polyfix= // A version that takes an array instead of multiple arguments would simply use l instead of (...l) for parameter
polyfix= // A version that takes an array instead of multiple arguments would simply use l instead of (...l) for parameter
(...l)=>(
(...l)=>(
Line 3,639: Line 3,639:
polyfix(
polyfix(
(even,odd)=>n=>(n===0)||odd(n-1),
(even,odd)=>n=>(n===0)||odd(n-1),
(even,odd)=>n=>(n!==0)&&even(n-1));</lang>
(even,odd)=>n=>(n!==0)&&even(n-1));</syntaxhighlight>


A minimalist version:
A minimalist version:


<lang javascript>var Y = f => (x => x(x))(y => f(x => y(y)(x)));
<syntaxhighlight lang="javascript">var Y = f => (x => x(x))(y => f(x => y(y)(x)));
var fac = Y(f => n => n > 1 ? n * f(n-1) : 1);</lang>
var fac = Y(f => n => n > 1 ? n * f(n-1) : 1);</syntaxhighlight>


=={{header|Joy}}==
=={{header|Joy}}==
<syntaxhighlight lang=Joy>DEFINE y == [dup cons] swap concat dup cons i;
<syntaxhighlight lang="joy">DEFINE y == [dup cons] swap concat dup cons i;
fac == [[pop null] [pop succ] [[dup pred] dip i *] ifte] y.</syntaxhighlight>
fac == [[pop null] [pop succ] [[dup pred] dip i *] ifte] y.</syntaxhighlight>


=={{header|Julia}}==
=={{header|Julia}}==
<lang julia>
<syntaxhighlight lang="julia">
_
_
_ _ _(_)_ | Documentation: https://docs.julialang.org
_ _ _(_)_ | Documentation: https://docs.julialang.org
Line 3,670: Line 3,670:
Y = f -> (x -> x(x))(y -> f((t...) -> y(y)(t...)))
Y = f -> (x -> x(x))(y -> f((t...) -> y(y)(t...)))
Y
Y
</syntaxhighlight>
</lang>


Usage:
Usage:


<lang julia>
<syntaxhighlight lang="julia">
julia> fac = f -> (n -> n < 2 ? 1 : n * f(n - 1))
julia> fac = f -> (n -> n < 2 ? 1 : n * f(n - 1))
#9 (generic function with 1 method)
#9 (generic function with 1 method)
Line 3,706: Line 3,706:
34
34
55
55
</syntaxhighlight>
</lang>


=={{header|Kitten}}==
=={{header|Kitten}}==


<lang kitten>define y<S..., T...> (S..., (S..., (S... -> T...) -> T...) -> T...):
<syntaxhighlight lang="kitten">define y<S..., T...> (S..., (S..., (S... -> T...) -> T...) -> T...):
-> f; { f y } f call
-> f; { f y } f call


Line 3,728: Line 3,728:
5 \fac y say // 120
5 \fac y say // 120
10 \fib y say // 55
10 \fib y say // 55
</syntaxhighlight>
</lang>


=={{header|Klingphix}}==
=={{header|Klingphix}}==
<syntaxhighlight lang="klingphix">:fac
<lang Klingphix>:fac
dup 1 great [dup 1 sub fac mult] if
dup 1 great [dup 1 sub fac mult] if
;
;
Line 3,751: Line 3,751:
@fac "fac" test
@fac "fac" test


"End " input</lang>
"End " input</syntaxhighlight>
{{out}}
{{out}}
<pre>fib: 1 1 2 3 5 8 13 21 34 55
<pre>fib: 1 1 2 3 5 8 13 21 34 55
Line 3,758: Line 3,758:


=={{header|Kotlin}}==
=={{header|Kotlin}}==
<lang scala>// version 1.1.2
<syntaxhighlight lang="scala">// version 1.1.2


typealias Func<T, R> = (T) -> R
typealias Func<T, R> = (T) -> R
Line 3,779: Line 3,779:
for (i in 1..10) print("${y(::fib)(i)} ")
for (i in 1..10) print("${y(::fib)(i)} ")
println()
println()
}</lang>
}</syntaxhighlight>


{{out}}
{{out}}
Line 3,790: Line 3,790:
Tested in http://lambdaway.free.fr/lambdawalks/?view=Ycombinator
Tested in http://lambdaway.free.fr/lambdawalks/?view=Ycombinator


<syntaxhighlight lang="scheme">
<lang Scheme>
1) defining the Ycombinator
1) defining the Ycombinator
{def Y {lambda {:f} {:f :f}}}
{def Y {lambda {:f} {:f :f}}}
Line 3,815: Line 3,815:
-> 34
-> 34


</syntaxhighlight>
</lang>


=={{header|Lua}}==
=={{header|Lua}}==
<lang lua>Y = function (f)
<syntaxhighlight lang="lua">Y = function (f)
return function(...)
return function(...)
return (function(x) return x(x) end)(function(x) return f(function(y) return x(x)(y) end) end)(...)
return (function(x) return x(x) end)(function(x) return f(function(y) return x(x)(y) end) end)(...)
end
end
end
end
</syntaxhighlight>
</lang>


Usage:
Usage:


<lang lua>almostfactorial = function(f) return function(n) return n > 0 and n * f(n-1) or 1 end end
<syntaxhighlight lang="lua">almostfactorial = function(f) return function(n) return n > 0 and n * f(n-1) or 1 end end
almostfibs = function(f) return function(n) return n < 2 and n or f(n-1) + f(n-2) end end
almostfibs = function(f) return function(n) return n < 2 and n or f(n-1) + f(n-2) end end
factorial, fibs = Y(almostfactorial), Y(almostfibs)
factorial, fibs = Y(almostfactorial), Y(almostfibs)
print(factorial(7))</lang>
print(factorial(7))</syntaxhighlight>


=={{header|M2000 Interpreter}}==
=={{header|M2000 Interpreter}}==
Lambda functions in M2000 are value types. They have a list of closures, but closures are copies, except for those closures which are reference types. Lambdas can keep state in closures (they are mutable). But here we didn't do that. Y combinator is a lambda which return a lambda with a closure as f function. This function called passing as first argument itself by value.
Lambda functions in M2000 are value types. They have a list of closures, but closures are copies, except for those closures which are reference types. Lambdas can keep state in closures (they are mutable). But here we didn't do that. Y combinator is a lambda which return a lambda with a closure as f function. This function called passing as first argument itself by value.
<syntaxhighlight lang="m2000 interpreter">
<lang M2000 Interpreter>
Module Ycombinator {
Module Ycombinator {
\\ y() return value. no use of closure
\\ y() return value. no use of closure
Line 3,849: Line 3,849:
}
}
Ycombinator
Ycombinator
</syntaxhighlight>
</lang>


<syntaxhighlight lang="m2000 interpreter">
<lang M2000 Interpreter>
Module Checkit {
Module Checkit {
Rem {
Rem {
Line 3,886: Line 3,886:
}
}
CheckRecursion
CheckRecursion
</syntaxhighlight>
</lang>


=={{header|MANOOL}}==
=={{header|MANOOL}}==
Here one additional technique is demonstrated: the Y combinator is applied to a function ''during compilation'' due to the <code>$</code> operator, which is optional:
Here one additional technique is demonstrated: the Y combinator is applied to a function ''during compilation'' due to the <code>$</code> operator, which is optional:
<syntaxhighlight lang="manool">
<lang MANOOL>
{ {extern "manool.org.18/std/0.3/all"} in
{ {extern "manool.org.18/std/0.3/all"} in
: let { Y = {proc {F} as {proc {X} as X[X]}[{proc {X} with {F} as F[{proc {Y} with {X} as X[X][Y]}]}]} } in
: let { Y = {proc {F} as {proc {X} as X[X]}[{proc {X} with {F} as F[{proc {Y} with {X} as X[X][Y]}]}]} } in
Line 3,902: Line 3,902:
}
}
}
}
</syntaxhighlight>
</lang>
Using less syntactic sugar:
Using less syntactic sugar:
<syntaxhighlight lang="manool">
<lang MANOOL>
{ {extern "manool.org.18/std/0.3/all"} in
{ {extern "manool.org.18/std/0.3/all"} in
: let { Y = {proc {F} as {proc {X} as X[X]}[{proc {F; X} as F[{proc {X; Y} as X[X][Y]}.Bind[X]]}.Bind[F]]} } in
: let { Y = {proc {F} as {proc {X} as X[X]}[{proc {F; X} as F[{proc {X; Y} as X[X][Y]}.Bind[X]]}.Bind[F]]} } in
Line 3,916: Line 3,916:
}
}
}
}
</syntaxhighlight>
</lang>
{{output}}
{{output}}
<pre>
<pre>
Line 3,942: Line 3,942:


=={{header|Maple}}==
=={{header|Maple}}==
<syntaxhighlight lang="maple">
<lang Maple>
> Y:=f->(x->x(x))(g->f((()->g(g)(args)))):
> Y:=f->(x->x(x))(g->f((()->g(g)(args)))):
> Yfac:=Y(f->(x->`if`(x<2,1,x*f(x-1)))):
> Yfac:=Y(f->(x->`if`(x<2,1,x*f(x-1)))):
Line 3,950: Line 3,950:
> seq( Yfib( i ), i = 1 .. 10 );
> seq( Yfib( i ), i = 1 .. 10 );
1, 1, 2, 3, 5, 8, 13, 21, 34, 55
1, 1, 2, 3, 5, 8, 13, 21, 34, 55
</syntaxhighlight>
</lang>


=={{header|Mathematica}} / {{header|Wolfram Language}}==
=={{header|Mathematica}} / {{header|Wolfram Language}}==
<lang Mathematica>Y = Function[f, #[#] &[Function[g, f[g[g][##] &]]]];
<syntaxhighlight lang="mathematica">Y = Function[f, #[#] &[Function[g, f[g[g][##] &]]]];
factorial = Y[Function[f, If[# < 1, 1, # f[# - 1]] &]];
factorial = Y[Function[f, If[# < 1, 1, # f[# - 1]] &]];
fibonacci = Y[Function[f, If[# < 2, #, f[# - 1] + f[# - 2]] &]];</lang>
fibonacci = Y[Function[f, If[# < 2, #, f[# - 1] + f[# - 2]] &]];</syntaxhighlight>


=={{header|Moonscript}}==
=={{header|Moonscript}}==
<lang Moonscript>Z = (f using nil) -> ((x) -> x x) (x) -> f (...) -> (x x) ...
<syntaxhighlight lang="moonscript">Z = (f using nil) -> ((x) -> x x) (x) -> f (...) -> (x x) ...
factorial = Z (f using nil) -> (n) -> if n == 0 then 1 else n * f n - 1</lang>
factorial = Z (f using nil) -> (n) -> if n == 0 then 1 else n * f n - 1</syntaxhighlight>


=={{header|Nim}}==
=={{header|Nim}}==


<lang nim># The following is implemented for a strict language as a Z-Combinator;
<syntaxhighlight lang="nim"># The following is implemented for a strict language as a Z-Combinator;
# Z-combinators differ from Y-combinators in lacking one Beta reduction of
# Z-combinators differ from Y-combinators in lacking one Beta reduction of
# the extra `T` argument to the function to be recursed...
# the extra `T` argument to the function to be recursed...
Line 4,034: Line 4,034:
let fibs = fibsy
let fibs = fibsy
for _ in 1 .. 20: stdout.write fibs(), " "
for _ in 1 .. 20: stdout.write fibs(), " "
echo()</lang>
echo()</syntaxhighlight>
{{out}}
{{out}}
<pre>3628800
<pre>3628800
Line 4,048: Line 4,048:
=={{header|Objective-C}}==
=={{header|Objective-C}}==
{{works with|Mac OS X|10.6+}}{{works with|iOS|4.0+}}
{{works with|Mac OS X|10.6+}}{{works with|iOS|4.0+}}
<lang objc>#import <Foundation/Foundation.h>
<syntaxhighlight lang="objc">#import <Foundation/Foundation.h>


typedef int (^Func)(int);
typedef int (^Func)(int);
Line 4,088: Line 4,088:
}
}
return 0;
return 0;
}</lang>
}</syntaxhighlight>


The usual version using recursion, disallowed by the task:
The usual version using recursion, disallowed by the task:
<lang objc>Func Y(FuncFunc f) {
<syntaxhighlight lang="objc">Func Y(FuncFunc f) {
return ^(int x) {
return ^(int x) {
return f(Y(f))(x);
return f(Y(f))(x);
};
};
}</lang>
}</syntaxhighlight>


=={{header|OCaml}}==
=={{header|OCaml}}==
The Y-combinator over functions may be written directly in OCaml provided rectypes are enabled:
The Y-combinator over functions may be written directly in OCaml provided rectypes are enabled:
<lang ocaml>let fix f g = (fun x a -> f (x x) a) (fun x a -> f (x x) a) g</lang>
<syntaxhighlight lang="ocaml">let fix f g = (fun x a -> f (x x) a) (fun x a -> f (x x) a) g</syntaxhighlight>
Polymorphic variants are the simplest workaround in the absence of rectypes:
Polymorphic variants are the simplest workaround in the absence of rectypes:
<lang ocaml>let fix f = (fun (`X x) -> f(x (`X x))) (`X(fun (`X x) y -> f(x (`X x)) y));;</lang>
<syntaxhighlight lang="ocaml">let fix f = (fun (`X x) -> f(x (`X x))) (`X(fun (`X x) y -> f(x (`X x)) y));;</syntaxhighlight>
Otherwise, an ordinary variant can be defined and used:
Otherwise, an ordinary variant can be defined and used:
<lang ocaml>type 'a mu = Roll of ('a mu -> 'a);;
<syntaxhighlight lang="ocaml">type 'a mu = Roll of ('a mu -> 'a);;


let unroll (Roll x) = x;;
let unroll (Roll x) = x;;
Line 4,129: Line 4,129:


fix fib 8;;
fix fib 8;;
(* - : int = 21 *)</lang>
(* - : int = 21 *)</syntaxhighlight>


The usual version using recursion, disallowed by the task:
The usual version using recursion, disallowed by the task:
<lang ocaml>let rec fix f x = f (fix f) x;;</lang>
<syntaxhighlight lang="ocaml">let rec fix f x = f (fix f) x;;</syntaxhighlight>


=={{header|Oforth}}==
=={{header|Oforth}}==
Line 4,138: Line 4,138:


With recursion into Y definition (so non stateless Y) :
With recursion into Y definition (so non stateless Y) :
<lang Oforth>: Y(f) #[ f Y f perform ] ;</lang>
<syntaxhighlight lang="oforth">: Y(f) #[ f Y f perform ] ;</syntaxhighlight>


Without recursion into Y definition (stateless Y).
Without recursion into Y definition (stateless Y).
<lang Oforth>: X(me, f) #[ me f me perform f perform ] ;
<syntaxhighlight lang="oforth">: X(me, f) #[ me f me perform f perform ] ;
: Y(f) #X f X ;</lang>
: Y(f) #X f X ;</syntaxhighlight>


Usage :
Usage :
<lang Oforth>: almost-fact(n, f) n ifZero: [ 1 ] else: [ n n 1 - f perform * ] ;
<syntaxhighlight lang="oforth">: almost-fact(n, f) n ifZero: [ 1 ] else: [ n n 1 - f perform * ] ;
#almost-fact Y => fact
#almost-fact Y => fact


Line 4,155: Line 4,155:
n 0 == ifTrue: [ 1 m 1 - f perform return ]
n 0 == ifTrue: [ 1 m 1 - f perform return ]
n 1 - m f perform m 1 - f perform ;
n 1 - m f perform m 1 - f perform ;
#almost-Ackermann Y => Ackermann </lang>
#almost-Ackermann Y => Ackermann </syntaxhighlight>


=={{header|Order}}==
=={{header|Order}}==
<lang c>#include <order/interpreter.h>
<syntaxhighlight lang="c">#include <order/interpreter.h>


#define ORDER_PP_DEF_8y \
#define ORDER_PP_DEF_8y \
Line 4,176: Line 4,176:


ORDER_PP(8to_lit(8ap(8y(8fac), 10))) // 3628800
ORDER_PP(8to_lit(8ap(8y(8fac), 10))) // 3628800
ORDER_PP(8ap(8y(8fib), 10)) // 55</lang>
ORDER_PP(8ap(8y(8fib), 10)) // 55</syntaxhighlight>


=={{header|Oz}}==
=={{header|Oz}}==
<lang oz>declare
<syntaxhighlight lang="oz">declare
Y = fun {$ F}
Y = fun {$ F}
{fun {$ X} {X X} end
{fun {$ X} {X X} end
Line 4,201: Line 4,201:
in
in
{Show {Fac 5}}
{Show {Fac 5}}
{Show {Fib 8}}</lang>
{Show {Fib 8}}</syntaxhighlight>


=={{header|PARI/GP}}==
=={{header|PARI/GP}}==
As of 2.8.0, GP cannot make general self-references in closures declared inline, so the Y combinator is required to implement these functions recursively in that environment, e.g., for use in parallel processing.
As of 2.8.0, GP cannot make general self-references in closures declared inline, so the Y combinator is required to implement these functions recursively in that environment, e.g., for use in parallel processing.
<lang parigp>Y(f)=x->f(f,x);
<syntaxhighlight lang="parigp">Y(f)=x->f(f,x);
fact=Y((f,n)->if(n,n*f(f,n-1),1));
fact=Y((f,n)->if(n,n*f(f,n-1),1));
fib=Y((f,n)->if(n>1,f(f,n-1)+f(f,n-2),n));
fib=Y((f,n)->if(n>1,f(f,n-1)+f(f,n-2),n));
apply(fact, [1..10])
apply(fact, [1..10])
apply(fib, [1..10])</lang>
apply(fib, [1..10])</syntaxhighlight>
{{out}}
{{out}}
<pre>%1 = [1, 2, 6, 24, 120, 720, 5040, 40320, 362880, 3628800]
<pre>%1 = [1, 2, 6, 24, 120, 720, 5040, 40320, 362880, 3628800]
Line 4,215: Line 4,215:


=={{header|Perl}}==
=={{header|Perl}}==
<lang perl>sub Y { my $f = shift; # λf.
<syntaxhighlight lang="perl">sub Y { my $f = shift; # λf.
sub { my $x = shift; $x->($x) }->( # (λx.x x)
sub { my $x = shift; $x->($x) }->( # (λx.x x)
sub {my $y = shift; $f->(sub {$y->($y)(@_)})} # λy.f λz.y y z
sub {my $y = shift; $f->(sub {$y->($y)(@_)})} # λy.f λz.y y z
Line 4,228: Line 4,228:
for my $f ($fac, $fib) {
for my $f ($fac, $fib) {
print join(' ', map Y($f)->($_), 0..9), "\n";
print join(' ', map Y($f)->($_), 0..9), "\n";
}</lang>
}</syntaxhighlight>
{{out}}
{{out}}
<pre>1 1 2 6 24 120 720 5040 40320 362880
<pre>1 1 2 6 24 120 720 5040 40320 362880
Line 4,234: Line 4,234:


The usual version using recursion, disallowed by the task:
The usual version using recursion, disallowed by the task:
<lang perl>sub Y { my $f = shift;
<syntaxhighlight lang="perl">sub Y { my $f = shift;
sub {$f->(Y($f))->(@_)}
sub {$f->(Y($f))->(@_)}
}</lang>
}</syntaxhighlight>


=={{header|Phix}}==
=={{header|Phix}}==
Line 4,249: Line 4,249:
[[Partial_function_application#Phix|Partial_function_application]],
[[Partial_function_application#Phix|Partial_function_application]],
and/or [[Function_composition#Phix|Function_composition]]
and/or [[Function_composition#Phix|Function_composition]]
<!--<lang Phix>(phixonline)-->
<!--<syntaxhighlight lang="phix">(phixonline)-->
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">call_fn</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">f</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">call_fn</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">f</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">)</span>
Line 4,277: Line 4,277:
<span style="color: #000000;">test</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"fac"</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">test</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"fac"</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">test</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"fib"</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">test</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"fib"</span><span style="color: #0000FF;">)</span>
<!--</lang>-->
<!--</syntaxhighlight>-->
{{out}}
{{out}}
<pre>
<pre>
Line 4,285: Line 4,285:


=={{header|Phixmonti}}==
=={{header|Phixmonti}}==
<lang Phixmonti>0 var subr
<syntaxhighlight lang="phixmonti">0 var subr


def fac
def fac
Line 4,309: Line 4,309:


getid fac "fac" test
getid fac "fac" test
getid fib "fib" test</lang>
getid fib "fib" test</syntaxhighlight>


=={{header|PHP}}==
=={{header|PHP}}==
{{works with|PHP|5.3+}}
{{works with|PHP|5.3+}}
<lang php><?php
<syntaxhighlight lang="php"><?php
function Y($f) {
function Y($f) {
$g = function($w) use($f) {
$g = function($w) use($f) {
Line 4,334: Line 4,334:


echo $factorial(10), "\n";
echo $factorial(10), "\n";
?></lang>
?></syntaxhighlight>
The usual version using recursion, disallowed by the task:
The usual version using recursion, disallowed by the task:
<lang php>function Y($f) {
<syntaxhighlight lang="php">function Y($f) {
return function() use($f) {
return function() use($f) {
return call_user_func_array($f(Y($f)), func_get_args());
return call_user_func_array($f(Y($f)), func_get_args());
};
};
}</lang>
}</syntaxhighlight>


{{works with|PHP|pre-5.3 and 5.3+}}
{{works with|PHP|pre-5.3 and 5.3+}}
with <tt>create_function</tt> instead of real closures. A little far-fetched, but...
with <tt>create_function</tt> instead of real closures. A little far-fetched, but...
<lang php><?php
<syntaxhighlight lang="php"><?php
function Y($f) {
function Y($f) {
$g = create_function('$w', '$f = '.var_export($f,true).';
$g = create_function('$w', '$f = '.var_export($f,true).';
Line 4,369: Line 4,369:
$factorial = Y('almost_fac');
$factorial = Y('almost_fac');
echo $factorial(10), "\n";
echo $factorial(10), "\n";
?></lang>
?></syntaxhighlight>


A functionally equivalent version using the <code>$this</code> parameter in closures is also possible:
A functionally equivalent version using the <code>$this</code> parameter in closures is also possible:
{{works with|PHP|5.4+}}
{{works with|PHP|5.4+}}
<lang php><?php
<syntaxhighlight lang="php"><?php
function pseudoY($f) {
function pseudoY($f) {
$g = function($w) use ($f) {
$g = function($w) use ($f) {
Line 4,392: Line 4,392:
});
});
echo $fibonacci(10), "\n";
echo $fibonacci(10), "\n";
?></lang>
?></syntaxhighlight>
However, <code>pseudoY()</code> is not a fixed-point combinator.
However, <code>pseudoY()</code> is not a fixed-point combinator.


=={{header|PicoLisp}}==
=={{header|PicoLisp}}==
{{trans|Common Lisp}}
{{trans|Common Lisp}}
<lang PicoLisp>(de Y (F)
<syntaxhighlight lang="picolisp">(de Y (F)
(let X (curry (F) (Y) (F (curry (Y) @ (pass (Y Y)))))
(let X (curry (F) (Y) (F (curry (Y) @ (pass (Y Y)))))
(X X) ) )</lang>
(X X) ) )</syntaxhighlight>
===Factorial===
===Factorial===
<lang PicoLisp># Factorial
<syntaxhighlight lang="picolisp"># Factorial
(de fact (F)
(de fact (F)
(curry (F) (N)
(curry (F) (N)
Line 4,409: Line 4,409:


: ((Y fact) 6)
: ((Y fact) 6)
-> 720</lang>
-> 720</syntaxhighlight>


===Fibonacci sequence===
===Fibonacci sequence===
<lang PicoLisp># Fibonacci
<syntaxhighlight lang="picolisp"># Fibonacci
(de fibo (F)
(de fibo (F)
(curry (F) (N)
(curry (F) (N)
Line 4,420: Line 4,420:


: ((Y fibo) 22)
: ((Y fibo) 22)
-> 28657</lang>
-> 28657</syntaxhighlight>


===Ackermann function===
===Ackermann function===
<lang PicoLisp># Ackermann
<syntaxhighlight lang="picolisp"># Ackermann
(de ack (F)
(de ack (F)
(curry (F) (X Y)
(curry (F) (X Y)
Line 4,432: Line 4,432:


: ((Y ack) 3 4)
: ((Y ack) 3 4)
-> 125</lang>
-> 125</syntaxhighlight>


=={{header|Pop11}}==
=={{header|Pop11}}==
<lang pop11>define Y(f);
<syntaxhighlight lang="pop11">define Y(f);
procedure (x); x(x) endprocedure(
procedure (x); x(x) endprocedure(
procedure (y);
procedure (y);
Line 4,456: Line 4,456:


Y(fac)(5) =>
Y(fac)(5) =>
Y(fib)(5) =></lang>
Y(fib)(5) =></syntaxhighlight>
{{out}}
{{out}}
<pre>
<pre>
Line 4,466: Line 4,466:
{{trans|Joy}}
{{trans|Joy}}
{{libheader|initlib}}
{{libheader|initlib}}
<lang postscript>y {
<syntaxhighlight lang="postscript">y {
{dup cons} exch concat dup cons i
{dup cons} exch concat dup cons i
}.
}.
Line 4,473: Line 4,473:
{ {pop zero?} {pop succ} {{dup pred} dip i *} ifte }
{ {pop zero?} {pop succ} {{dup pred} dip i *} ifte }
y
y
}.</lang>
}.</syntaxhighlight>


=={{header|PowerShell}}==
=={{header|PowerShell}}==
Line 4,484: Line 4,484:
Z & := & \lambda f.(\lambda x.f\ (\lambda y.x\ x\ y))\ (\lambda x.f\ (\lambda y.x\ x\ y)) \\
Z & := & \lambda f.(\lambda x.f\ (\lambda y.x\ x\ y))\ (\lambda x.f\ (\lambda y.x\ x\ y)) \\
\end{array}</math>
\end{array}</math>
<lang PowerShell>$fac = {
<syntaxhighlight lang="powershell">$fac = {
param([ScriptBlock] $f)
param([ScriptBlock] $f)
invoke-expression @"
invoke-expression @"
Line 4,534: Line 4,534:


$Z.InvokeReturnAsIs($fac).InvokeReturnAsIs(5)
$Z.InvokeReturnAsIs($fac).InvokeReturnAsIs(5)
$Z.InvokeReturnAsIs($fib).InvokeReturnAsIs(5)</lang>
$Z.InvokeReturnAsIs($fib).InvokeReturnAsIs(5)</syntaxhighlight>




GetNewClosure() was added in Powershell 2, allowing for an implementation without metaprogramming. The following was tested with Powershell 4.
GetNewClosure() was added in Powershell 2, allowing for an implementation without metaprogramming. The following was tested with Powershell 4.


<lang PowerShell>$Y = {
<syntaxhighlight lang="powershell">$Y = {
param ($f)
param ($f)


Line 4,586: Line 4,586:


$Y.invoke($fact).invoke(5)
$Y.invoke($fact).invoke(5)
$Y.invoke($fib).invoke(5)</lang>
$Y.invoke($fib).invoke(5)</syntaxhighlight>


=={{header|Prolog}}==
=={{header|Prolog}}==
Line 4,593: Line 4,593:
The code is inspired from this page : http://www.complang.tuwien.ac.at/ulrich/Prolog-inedit/ISO-Hiord#Hiord (p 106). <br>
The code is inspired from this page : http://www.complang.tuwien.ac.at/ulrich/Prolog-inedit/ISO-Hiord#Hiord (p 106). <br>
Original code is from <b>Hermenegildo</b> and al : <b>Hiord: A Type-Free Higher-Order Logic Programming Language with Predicate Abstraction</b>, pdf accessible here http://www.stups.uni-duesseldorf.de/asap/?id=129.
Original code is from <b>Hermenegildo</b> and al : <b>Hiord: A Type-Free Higher-Order Logic Programming Language with Predicate Abstraction</b>, pdf accessible here http://www.stups.uni-duesseldorf.de/asap/?id=129.
<lang Prolog>:- use_module(lambda).
<syntaxhighlight lang="prolog">:- use_module(lambda).


% The Y combinator
% The Y combinator
Line 4,624: Line 4,624:
),
),


y(Fact, 10, FF), format('Fact(~w) = ~w~n', [10, FF]).</lang>
y(Fact, 10, FF), format('Fact(~w) = ~w~n', [10, FF]).</syntaxhighlight>
{{out}}
{{out}}
<pre>
<pre>
Line 4,633: Line 4,633:


=={{header|Python}}==
=={{header|Python}}==
<lang python>>>> Y = lambda f: (lambda x: x(x))(lambda y: f(lambda *args: y(y)(*args)))
<syntaxhighlight lang="python">>>> Y = lambda f: (lambda x: x(x))(lambda y: f(lambda *args: y(y)(*args)))
>>> fac = lambda f: lambda n: (1 if n<2 else n*f(n-1))
>>> fac = lambda f: lambda n: (1 if n<2 else n*f(n-1))
>>> [ Y(fac)(i) for i in range(10) ]
>>> [ Y(fac)(i) for i in range(10) ]
Line 4,639: Line 4,639:
>>> fib = lambda f: lambda n: 0 if n == 0 else (1 if n == 1 else f(n-1) + f(n-2))
>>> fib = lambda f: lambda n: 0 if n == 0 else (1 if n == 1 else f(n-1) + f(n-2))
>>> [ Y(fib)(i) for i in range(10) ]
>>> [ Y(fib)(i) for i in range(10) ]
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34]</lang>
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34]</syntaxhighlight>


The usual version using recursion, disallowed by the task:
The usual version using recursion, disallowed by the task:
<lang python>Y = lambda f: lambda *args: f(Y(f))(*args)</lang>
<syntaxhighlight lang="python">Y = lambda f: lambda *args: f(Y(f))(*args)</syntaxhighlight>


<lang python>Y = lambda b: ((lambda f: b(lambda *x: f(f)(*x)))((lambda f: b(lambda *x: f(f)(*x)))))</lang>
<syntaxhighlight lang="python">Y = lambda b: ((lambda f: b(lambda *x: f(f)(*x)))((lambda f: b(lambda *x: f(f)(*x)))))</syntaxhighlight>


=={{header|Q}}==
=={{header|Q}}==
<lang Q>> Y: {{x x} {({y {(x x) y} x} y) x} x}
<syntaxhighlight lang="q">> Y: {{x x} {({y {(x x) y} x} y) x} x}
> fac: {{$[y<2; 1; y*x y-1]} x}
> fac: {{$[y<2; 1; y*x y-1]} x}
> (Y fac) 6
> (Y fac) 6
Line 4,654: Line 4,654:
> (Y fib) each til 20
> (Y fib) each til 20
1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181 6765
1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181 6765
</syntaxhighlight>
</lang>


=={{header|Quackery}}==
=={{header|Quackery}}==
Line 4,668: Line 4,668:
Without the restriction on self referencing, <code>recursive</code> could be defined as <code>[ ' [ this ] swap nested join ]</code>.
Without the restriction on self referencing, <code>recursive</code> could be defined as <code>[ ' [ this ] swap nested join ]</code>.


<lang Quackery> [ ' stack nested nested
<syntaxhighlight lang="quackery"> [ ' stack nested nested
' share nested join
' share nested join
swap nested join
swap nested join
Line 4,682: Line 4,682:


say "8 factorial = " 8 ' factorial recursive do echo cr
say "8 factorial = " 8 ' factorial recursive do echo cr
say "8 fibonacci = " 8 ' fibonacci recursive do echo cr</lang>
say "8 fibonacci = " 8 ' fibonacci recursive do echo cr</syntaxhighlight>


{{out}}
{{out}}
Line 4,691: Line 4,691:


=={{header|R}}==
=={{header|R}}==
<lang R>Y <- function(f) {
<syntaxhighlight lang="r">Y <- function(f) {
(function(x) { (x)(x) })( function(y) { f( (function(a) {y(y)})(a) ) } )
(function(x) { (x)(x) })( function(y) { f( (function(a) {y(y)})(a) ) } )
}</lang>
}</syntaxhighlight>


<lang R>fac <- function(f) {
<syntaxhighlight lang="r">fac <- function(f) {
function(n) {
function(n) {
if (n<2)
if (n<2)
Line 4,711: Line 4,711:
f(n-1) + f(n-2)
f(n-1) + f(n-2)
}
}
}</lang>
}</syntaxhighlight>


<lang R>for(i in 1:9) print(Y(fac)(i))
<syntaxhighlight lang="r">for(i in 1:9) print(Y(fac)(i))
for(i in 1:9) print(Y(fib)(i))</lang>
for(i in 1:9) print(Y(fib)(i))</syntaxhighlight>


=={{header|Racket}}==
=={{header|Racket}}==


The lazy implementation
The lazy implementation
<lang racket>#lang lazy
<syntaxhighlight lang="racket">#lang lazy


(define Y (λ (f) ((λ (x) (f (x x))) (λ (x) (f (x x))))))
(define Y (λ (f) ((λ (x) (f (x x))) (λ (x) (f (x x))))))
Line 4,726: Line 4,726:
(Y (λ (fact) (λ (n) (if (zero? n) 1 (* n (fact (- n 1))))))))
(Y (λ (fact) (λ (n) (if (zero? n) 1 (* n (fact (- n 1))))))))
(define Fib
(define Fib
(Y (λ (fib) (λ (n) (if (<= n 1) n (+ (fib (- n 1)) (fib (- n 2))))))))</lang>
(Y (λ (fib) (λ (n) (if (<= n 1) n (+ (fib (- n 1)) (fib (- n 2))))))))</syntaxhighlight>


{{out}}
{{out}}
Line 4,737: Line 4,737:


Strict realization:
Strict realization:
<lang racket>#lang racket
<syntaxhighlight lang="racket">#lang racket
(define Y (λ (b) ((λ (f) (b (λ (x) ((f f) x))))
(define Y (λ (b) ((λ (f) (b (λ (x) ((f f) x))))
(λ (f) (b (λ (x) ((f f) x)))))))</lang>
(λ (f) (b (λ (x) ((f f) x)))))))</syntaxhighlight>


Definitions of <tt>Fact</tt> and <tt>Fib</tt> functions will be the same as in Lazy Racket.
Definitions of <tt>Fact</tt> and <tt>Fib</tt> functions will be the same as in Lazy Racket.


Finally, a definition in Typed Racket is a little difficult as in other statically typed languages:
Finally, a definition in Typed Racket is a little difficult as in other statically typed languages:
<lang racket>#lang typed/racket
<syntaxhighlight lang="racket">#lang typed/racket


(: make-recursive : (All (S T) ((S -> T) -> (S -> T)) -> (S -> T)))
(: make-recursive : (All (S T) ((S -> T) -> (S -> T)) -> (S -> T)))
Line 4,760: Line 4,760:
(* n (fact (- n 1))))))))
(* n (fact (- n 1))))))))


(fact 5)</lang>
(fact 5)</syntaxhighlight>


=={{header|Raku}}==
=={{header|Raku}}==
(formerly Perl 6)
(formerly Perl 6)
<lang perl6>sub Y (&f) { sub (&x) { x(&x) }( sub (&y) { f(sub ($x) { y(&y)($x) }) } ) }
<syntaxhighlight lang="raku" line>sub Y (&f) { sub (&x) { x(&x) }( sub (&y) { f(sub ($x) { y(&y)($x) }) } ) }
sub fac (&f) { sub ($n) { $n < 2 ?? 1 !! $n * f($n - 1) } }
sub fac (&f) { sub ($n) { $n < 2 ?? 1 !! $n * f($n - 1) } }
sub fib (&f) { sub ($n) { $n < 2 ?? $n !! f($n - 1) + f($n - 2) } }
sub fib (&f) { sub ($n) { $n < 2 ?? $n !! f($n - 1) + f($n - 2) } }
say map Y($_), ^10 for &fac, &fib;</lang>
say map Y($_), ^10 for &fac, &fib;</syntaxhighlight>
{{out}}
{{out}}
<pre>(1 1 2 6 24 120 720 5040 40320 362880)
<pre>(1 1 2 6 24 120 720 5040 40320 362880)
Line 4,774: Line 4,774:
Note that Raku doesn't actually need a Y combinator because you can name anonymous functions from the inside:
Note that Raku doesn't actually need a Y combinator because you can name anonymous functions from the inside:


<lang perl6>say .(10) given sub (Int $x) { $x < 2 ?? 1 !! $x * &?ROUTINE($x - 1); }</lang>
<syntaxhighlight lang="raku" line>say .(10) given sub (Int $x) { $x < 2 ?? 1 !! $x * &?ROUTINE($x - 1); }</syntaxhighlight>


=={{header|REBOL}}==
=={{header|REBOL}}==
<lang rebol>Y: closure [g] [do func [f] [f :f] closure [f] [g func [x] [do f :f :x]]]</lang>
<syntaxhighlight lang="rebol">Y: closure [g] [do func [f] [f :f] closure [f] [g func [x] [do f :f :x]]]</syntaxhighlight>
;usage example
;usage example
<lang rebol>fact*: closure [h] [func [n] [either n <= 1 [1] [n * h n - 1]]]
<syntaxhighlight lang="rebol">fact*: closure [h] [func [n] [either n <= 1 [1] [n * h n - 1]]]
fact: Y :fact*</lang>
fact: Y :fact*</syntaxhighlight>


=={{header|REXX}}==
=={{header|REXX}}==
Programming note: &nbsp; '''length''', &nbsp; '''reverse''', &nbsp; '''sign''', &nbsp; '''trunc''', &nbsp; '''b2x''', &nbsp; '''d2x''', &nbsp; and &nbsp; '''x2d''' &nbsp; are REXX BIFs &nbsp; ('''B'''uilt '''I'''n '''F'''unctions).
Programming note: &nbsp; '''length''', &nbsp; '''reverse''', &nbsp; '''sign''', &nbsp; '''trunc''', &nbsp; '''b2x''', &nbsp; '''d2x''', &nbsp; and &nbsp; '''x2d''' &nbsp; are REXX BIFs &nbsp; ('''B'''uilt '''I'''n '''F'''unctions).
<lang rexx>/*REXX program implements and displays a stateless Y combinator. */
<syntaxhighlight lang="rexx">/*REXX program implements and displays a stateless Y combinator. */
numeric digits 1000 /*allow big numbers. */
numeric digits 1000 /*allow big numbers. */
say ' fib' Y(fib (50) ) /*Fibonacci series. */
say ' fib' Y(fib (50) ) /*Fibonacci series. */
Line 4,810: Line 4,810:
tfact: procedure; parse arg x; != 1; do j=x to 2 by -3; != !*j; end; return !
tfact: procedure; parse arg x; != 1; do j=x to 2 by -3; != !*j; end; return !
qfact: procedure; parse arg x; != 1; do j=x to 2 by -4; != !*j; end; return !
qfact: procedure; parse arg x; != 1; do j=x to 2 by -4; != !*j; end; return !
fact: procedure; parse arg x; != 1; do j=2 to x ; != !*j; end; return !</lang>
fact: procedure; parse arg x; != 1; do j=2 to x ; != !*j; end; return !</syntaxhighlight>
{{out|output|text=&nbsp; when using the internal default input:}}
{{out|output|text=&nbsp; when using the internal default input:}}
<pre>
<pre>
Line 4,832: Line 4,832:
Using a lambda:
Using a lambda:


<lang ruby>y = lambda do |f|
<syntaxhighlight lang="ruby">y = lambda do |f|
lambda {|g| g[g]}[lambda do |g|
lambda {|g| g[g]}[lambda do |g|
f[lambda {|*args| g[g][*args]}]
f[lambda {|*args| g[g][*args]}]
Line 4,842: Line 4,842:


fib = lambda{|f| lambda{|n| n < 2 ? n : f[n-1] + f[n-2]}}
fib = lambda{|f| lambda{|n| n < 2 ? n : f[n-1] + f[n-2]}}
p Array.new(10) {|i| y[fib][i]} #=> [0, 1, 1, 2, 3, 5, 8, 13, 21, 34]</lang>
p Array.new(10) {|i| y[fib][i]} #=> [0, 1, 1, 2, 3, 5, 8, 13, 21, 34]</syntaxhighlight>


Same as the above, using the new short lambda syntax:
Same as the above, using the new short lambda syntax:
{{works with|Ruby|1.9}}
{{works with|Ruby|1.9}}
<lang ruby>y = ->(f) {->(g) {g.(g)}.(->(g) { f.(->(*args) {g.(g).(*args)})})}
<syntaxhighlight lang="ruby">y = ->(f) {->(g) {g.(g)}.(->(g) { f.(->(*args) {g.(g).(*args)})})}
fac = ->(f) { ->(n) { n < 2 ? 1 : n * f.(n-1) } }
fac = ->(f) { ->(n) { n < 2 ? 1 : n * f.(n-1) } }
Line 4,854: Line 4,854:
fib = ->(f) { ->(n) { n < 2 ? n : f.(n-2) + f.(n-1) } }
fib = ->(f) { ->(n) { n < 2 ? n : f.(n-2) + f.(n-1) } }


p 10.times.map {|i| y.(fib).(i)}</lang>
p 10.times.map {|i| y.(fib).(i)}</syntaxhighlight>


Using a method:
Using a method:


{{works with|Ruby|1.9}}
{{works with|Ruby|1.9}}
<lang ruby>def y(&f)
<syntaxhighlight lang="ruby">def y(&f)
lambda do |g|
lambda do |g|
f.call {|*args| g[g][*args]}
f.call {|*args| g[g][*args]}
Line 4,871: Line 4,871:
# => [1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880]
# => [1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880]
p Array.new(10) {|i| fib[i]}
p Array.new(10) {|i| fib[i]}
# => [0, 1, 1, 2, 3, 5, 8, 13, 21, 34]</lang>
# => [0, 1, 1, 2, 3, 5, 8, 13, 21, 34]</syntaxhighlight>


The usual version using recursion, disallowed by the task:
The usual version using recursion, disallowed by the task:
<lang ruby>y = lambda do |f|
<syntaxhighlight lang="ruby">y = lambda do |f|
lambda {|*args| f[y[f]][*args]}
lambda {|*args| f[y[f]][*args]}
end</lang>
end</syntaxhighlight>


=={{header|Rust}}==
=={{header|Rust}}==


{{works with|Rust|1.44.1 stable}}
{{works with|Rust|1.44.1 stable}}
<lang rust>
<syntaxhighlight lang="rust">
//! A simple implementation of the Y Combinator:
//! A simple implementation of the Y Combinator:
//! λf.(λx.xx)(λx.f(xx))
//! λf.(λx.xx)(λx.f(xx))
Line 4,936: Line 4,936:
}
}


</syntaxhighlight>
</lang>
{{output}}
{{output}}
<pre>
<pre>
Line 4,945: Line 4,945:
=={{header|Scala}}==
=={{header|Scala}}==
Credit goes to the thread in [https://web.archive.org/web/20160709050901/http://scala-blogs.org/2008/09/y-combinator-in-scala.html scala blog]
Credit goes to the thread in [https://web.archive.org/web/20160709050901/http://scala-blogs.org/2008/09/y-combinator-in-scala.html scala blog]
<lang scala>
<syntaxhighlight lang="scala">
def Y[A, B](f: (A => B) => (A => B)): A => B = {
def Y[A, B](f: (A => B) => (A => B)): A => B = {
case class W(wf: W => (A => B)) {
case class W(wf: W => (A => B)) {
Line 4,953: Line 4,953:
g(W(g))
g(W(g))
}
}
</syntaxhighlight>
</lang>
Example
Example
<lang scala>
<syntaxhighlight lang="scala">
val fac: Int => Int = Y[Int, Int](f => i => if (i <= 0) 1 else f(i - 1) * i)
val fac: Int => Int = Y[Int, Int](f => i => if (i <= 0) 1 else f(i - 1) * i)
fac(6) //> res0: Int = 720
fac(6) //> res0: Int = 720
Line 4,961: Line 4,961:
val fib: Int => Int = Y[Int, Int](f => i => if (i < 2) i else f(i - 1) + f(i - 2))
val fib: Int => Int = Y[Int, Int](f => i => if (i < 2) i else f(i - 1) + f(i - 2))
fib(6) //> res1: Int = 8
fib(6) //> res1: Int = 8
</syntaxhighlight>
</lang>


=={{header|Scheme}}==
=={{header|Scheme}}==
<lang scheme>(define Y ; (Y f) = (g g) where
<syntaxhighlight lang="scheme">(define Y ; (Y f) = (g g) where
(lambda (f) ; (g g) = (f (lambda a (apply (g g) a)))
(lambda (f) ; (g g) = (f (lambda a (apply (g g) a)))
((lambda (g) (g g)) ; (Y f) == (f (lambda a (apply (Y f) a)))
((lambda (g) (g g)) ; (Y f) == (f (lambda a (apply (Y f) a)))
Line 5,010: Line 5,010:


(display (fib2 134))
(display (fib2 134))
(newline)</lang>
(newline)</syntaxhighlight>
{{out}}
{{out}}
<pre>720
<pre>720
Line 5,017: Line 5,017:
If we were allowed to use recursion (with <code>Y</code> referring to itself by name in its body) we could define the equivalent to the above as
If we were allowed to use recursion (with <code>Y</code> referring to itself by name in its body) we could define the equivalent to the above as


<lang scheme>(define Yr ; (Y f) == (f (lambda a (apply (Y f) a)))
<syntaxhighlight lang="scheme">(define Yr ; (Y f) == (f (lambda a (apply (Y f) a)))
(lambda (f)
(lambda (f)
(f (lambda a (apply (Yr f) a)))))</lang>
(f (lambda a (apply (Yr f) a)))))</syntaxhighlight>


And another way is:
And another way is:
<lang scheme>(define Y2r
<syntaxhighlight lang="scheme">(define Y2r
(lambda (f)
(lambda (f)
(lambda a (apply (f (Y2r f)) a))))</lang>
(lambda a (apply (f (Y2r f)) a))))</syntaxhighlight>


Which, non-recursively, is
Which, non-recursively, is
<lang scheme>(define Y2 ; (Y2 f) = (g g) where
<syntaxhighlight lang="scheme">(define Y2 ; (Y2 f) = (g g) where
(lambda (f) ; (g g) = (lambda a (apply (f (g g)) a))
(lambda (f) ; (g g) = (lambda a (apply (f (g g)) a))
((lambda (g) (g g)) ; (Y2 f) == (lambda a (apply (f (Y2 f)) a))
((lambda (g) (g g)) ; (Y2 f) == (lambda a (apply (f (Y2 f)) a))
(lambda (g)
(lambda (g)
(lambda a (apply (f (g g)) a))))))</lang>
(lambda a (apply (f (g g)) a))))))</syntaxhighlight>


=={{header|Shen}}==
=={{header|Shen}}==
<lang shen>(define y
<syntaxhighlight lang="shen">(define y
F -> ((/. X (X X))
F -> ((/. X (X X))
(/. X (F (/. Z ((X X) Z))))))
(/. X (F (/. Z ((X X) Z))))))
Line 5,044: Line 5,044:
(Fac 0)
(Fac 0)
(Fac 5)
(Fac 5)
(Fac 10)))</lang>
(Fac 10)))</syntaxhighlight>
{{out}}
{{out}}
<pre>1
<pre>1
Line 5,051: Line 5,051:


=={{header|Sidef}}==
=={{header|Sidef}}==
<lang ruby>var y = ->(f) {->(g) {g(g)}(->(g) { f(->(*args) {g(g)(args...)})})}
<syntaxhighlight lang="ruby">var y = ->(f) {->(g) {g(g)}(->(g) { f(->(*args) {g(g)(args...)})})}


var fac = ->(f) { ->(n) { n < 2 ? 1 : (n * f(n-1)) } }
var fac = ->(f) { ->(n) { n < 2 ? 1 : (n * f(n-1)) } }
Line 5,057: Line 5,057:


var fib = ->(f) { ->(n) { n < 2 ? n : (f(n-2) + f(n-1)) } }
var fib = ->(f) { ->(n) { n < 2 ? n : (f(n-2) + f(n-1)) } }
say 10.of { |i| y(fib)(i) }</lang>
say 10.of { |i| y(fib)(i) }</syntaxhighlight>
{{out}}
{{out}}
<pre>
<pre>
Line 5,066: Line 5,066:
=={{header|Slate}}==
=={{header|Slate}}==
The Y combinator is already defined in slate as:
The Y combinator is already defined in slate as:
<lang slate>Method traits define: #Y &builder:
<syntaxhighlight lang="slate">Method traits define: #Y &builder:
[[| :f | [| :x | f applyWith: (x applyWith: x)]
[[| :f | [| :x | f applyWith: (x applyWith: x)]
applyWith: [| :x | f applyWith: (x applyWith: x)]]].</lang>
applyWith: [| :x | f applyWith: (x applyWith: x)]]].</syntaxhighlight>


=={{header|Smalltalk}}==
=={{header|Smalltalk}}==
{{works with|GNU Smalltalk}}
{{works with|GNU Smalltalk}}
<lang smalltalk>Y := [:f| [:x| x value: x] value: [:g| f value: [:x| (g value: g) value: x] ] ].
<syntaxhighlight lang="smalltalk">Y := [:f| [:x| x value: x] value: [:g| f value: [:x| (g value: g) value: x] ] ].


fib := Y value: [:f| [:i| i <= 1 ifTrue: [i] ifFalse: [(f value: i-1) + (f value: i-2)] ] ].
fib := Y value: [:f| [:i| i <= 1 ifTrue: [i] ifFalse: [(f value: i-1) + (f value: i-2)] ] ].
Line 5,080: Line 5,080:
fact := Y value: [:f| [:i| i = 0 ifTrue: [1] ifFalse: [(f value: i-1) * i] ] ].
fact := Y value: [:f| [:i| i = 0 ifTrue: [1] ifFalse: [(f value: i-1) * i] ] ].


(fact value: 10) displayNl.</lang>
(fact value: 10) displayNl.</syntaxhighlight>
{{out}}
{{out}}
<pre>55
<pre>55
Line 5,086: Line 5,086:


The usual version using recursion, disallowed by the task:
The usual version using recursion, disallowed by the task:
<lang smalltalk>Y := [:f| [:x| (f value: (Y value: f)) value: x] ].</lang>
<syntaxhighlight lang="smalltalk">Y := [:f| [:x| (f value: (Y value: f)) value: x] ].</syntaxhighlight>


=={{header|Standard ML}}==
=={{header|Standard ML}}==
<lang sml>- datatype 'a mu = Roll of ('a mu -> 'a)
<syntaxhighlight lang="sml">- datatype 'a mu = Roll of ('a mu -> 'a)
fun unroll (Roll x) = x
fun unroll (Roll x) = x


Line 5,109: Line 5,109:
val it = [1,1,2,6,24,120,720,5040,40320,362880] : int list
val it = [1,1,2,6,24,120,720,5040,40320,362880] : int list
- List.tabulate (10, fix fib);
- List.tabulate (10, fix fib);
val it = [0,1,1,2,3,5,8,13,21,34] : int list</lang>
val it = [0,1,1,2,3,5,8,13,21,34] : int list</syntaxhighlight>


The usual version using recursion, disallowed by the task:
The usual version using recursion, disallowed by the task:
<lang sml>fun fix f x = f (fix f) x</lang>
<syntaxhighlight lang="sml">fun fix f x = f (fix f) x</syntaxhighlight>


=={{header|SuperCollider}}==
=={{header|SuperCollider}}==
Like Ruby, SuperCollider needs an extra level of lambda-abstraction to implement the y-combinator. The z-combinator is straightforward:
Like Ruby, SuperCollider needs an extra level of lambda-abstraction to implement the y-combinator. The z-combinator is straightforward:
<lang SuperCollider>// z-combinator
<syntaxhighlight lang="supercollider">// z-combinator
(
(
z = { |f|
z = { |f|
Line 5,157: Line 5,157:




</syntaxhighlight>
</lang>


=={{header|Swift}}==
=={{header|Swift}}==
Using a recursive type:
Using a recursive type:
<lang swift>struct RecursiveFunc<F> {
<syntaxhighlight lang="swift">struct RecursiveFunc<F> {
let o : RecursiveFunc<F> -> F
let o : RecursiveFunc<F> -> F
}
}
Line 5,177: Line 5,177:
}
}
println("fac(5) = \(fac(5))")
println("fac(5) = \(fac(5))")
println("fib(9) = \(fib(9))")</lang>
println("fib(9) = \(fib(9))")</syntaxhighlight>
{{out}}
{{out}}
<pre>
<pre>
Line 5,186: Line 5,186:
Without a recursive type, and instead using <code>Any</code> to erase the type:
Without a recursive type, and instead using <code>Any</code> to erase the type:
{{works with|Swift|1.2+}} (for Swift 1.1 replace <code>as!</code> with <code>as</code>)
{{works with|Swift|1.2+}} (for Swift 1.1 replace <code>as!</code> with <code>as</code>)
<lang swift>func Y<A, B>(f: (A -> B) -> A -> B) -> A -> B {
<syntaxhighlight lang="swift">func Y<A, B>(f: (A -> B) -> A -> B) -> A -> B {
typealias RecursiveFunc = Any -> A -> B
typealias RecursiveFunc = Any -> A -> B
let r : RecursiveFunc = { (z: Any) in let w = z as! RecursiveFunc; return f { w(w)($0) } }
let r : RecursiveFunc = { (z: Any) in let w = z as! RecursiveFunc; return f { w(w)($0) } }
return r(r)
return r(r)
}</lang>
}</syntaxhighlight>


The usual version using recursion, disallowed by the task:
The usual version using recursion, disallowed by the task:
<lang swift>func Y<In, Out>( f: (In->Out) -> (In->Out) ) -> (In->Out) {
<syntaxhighlight lang="swift">func Y<In, Out>( f: (In->Out) -> (In->Out) ) -> (In->Out) {
return { x in f(Y(f))(x) }
return { x in f(Y(f))(x) }
}</lang>
}</syntaxhighlight>


=={{header|Tailspin}}==
=={{header|Tailspin}}==
<lang tailspin>
<syntaxhighlight lang="tailspin">
// YCombinator is not needed since tailspin supports recursion readily, but this demonstrates passing functions as parameters
// YCombinator is not needed since tailspin supports recursion readily, but this demonstrates passing functions as parameters
Line 5,231: Line 5,231:
5 -> fibonacci -> 'fibonacci 5: $;
5 -> fibonacci -> 'fibonacci 5: $;
' -> !OUT::write
' -> !OUT::write
</syntaxhighlight>
</lang>
{{out}}
{{out}}
<pre>
<pre>
Line 5,244: Line 5,244:
This prints out 24, the factorial of 4:
This prints out 24, the factorial of 4:


<lang txrlisp>;; The Y combinator:
<syntaxhighlight lang="txrlisp">;; The Y combinator:
(defun y (f)
(defun y (f)
[(op @1 @1)
[(op @1 @1)
Line 5,256: Line 5,256:


;; Test:
;; Test:
(format t "~s\n" [[y fac] 4])</lang>
(format t "~s\n" [[y fac] 4])</syntaxhighlight>


Both the <code>op</code> and <code>do</code> operators are a syntactic sugar for currying, in two different flavors. The forms within <code>do</code> that are symbols are evaluated in the normal Lisp-2 style and the first symbol can be an operator. Under <code>op</code>, any forms that are symbols are evaluated in the Lisp-2 style, and the first form is expected to evaluate to a function. The name <code>do</code> stems from the fact that the operator is used for currying over special forms like <code>if</code> in the above example, where there is evaluation control. Operators can have side effects: they can "do" something. Consider <code>(do set a @1)</code> which yields a function of one argument which assigns that argument to <code>a</code>.
Both the <code>op</code> and <code>do</code> operators are a syntactic sugar for currying, in two different flavors. The forms within <code>do</code> that are symbols are evaluated in the normal Lisp-2 style and the first symbol can be an operator. Under <code>op</code>, any forms that are symbols are evaluated in the Lisp-2 style, and the first form is expected to evaluate to a function. The name <code>do</code> stems from the fact that the operator is used for currying over special forms like <code>if</code> in the above example, where there is evaluation control. Operators can have side effects: they can "do" something. Consider <code>(do set a @1)</code> which yields a function of one argument which assigns that argument to <code>a</code>.


The compounded <code>@@...</code> notation allows for inner functions to refer to outer parameters, when the notation is nested. Consider <lang txrlisp>(op foo @1 (op bar @2 @@2))</lang>. Here the <code>@2</code> refers to the second argument of the anonymous function denoted by the inner <code>op</code>. The <code>@@2</code> refers to the second argument of the outer <code>op</code>.
The compounded <code>@@...</code> notation allows for inner functions to refer to outer parameters, when the notation is nested. Consider <syntaxhighlight lang="txrlisp">(op foo @1 (op bar @2 @@2))</syntaxhighlight>. Here the <code>@2</code> refers to the second argument of the anonymous function denoted by the inner <code>op</code>. The <code>@@2</code> refers to the second argument of the outer <code>op</code>.


=={{header|Ursala}}==
=={{header|Ursala}}==
The standard y combinator doesn't work in Ursala due to eager
The standard y combinator doesn't work in Ursala due to eager
evaluation, but an alternative is easily defined as shown
evaluation, but an alternative is easily defined as shown
<lang Ursala>(r "f") "x" = "f"("f","x")
<syntaxhighlight lang="ursala">(r "f") "x" = "f"("f","x")
my_fix "h" = r ("f","x"). ("h" r "f") "x"</lang>
my_fix "h" = r ("f","x"). ("h" r "f") "x"</syntaxhighlight>
or by this shorter expression for the same thing in point free form.
or by this shorter expression for the same thing in point free form.
<lang Ursala>my_fix = //~&R+ ^|H\~&+ ; //~&R</lang>
<syntaxhighlight lang="ursala">my_fix = //~&R+ ^|H\~&+ ; //~&R</syntaxhighlight>
Normally you'd like to define a function recursively by writing
Normally you'd like to define a function recursively by writing
<math>f = h(f)</math>, where <math>h(f)</math> is just the body of the
<math>f = h(f)</math>, where <math>h(f)</math> is just the body of the
Line 5,276: Line 5,276:
quotes signify a dummy variable. Using this
quotes signify a dummy variable. Using this
method, the definition of the factorial function becomes
method, the definition of the factorial function becomes
<lang Ursala>#import nat
<syntaxhighlight lang="ursala">#import nat


fact = my_fix "f". ~&?\1! product^/~& "f"+ predecessor</lang>
fact = my_fix "f". ~&?\1! product^/~& "f"+ predecessor</syntaxhighlight>
To make it easier, the compiler has a directive to let you install
To make it easier, the compiler has a directive to let you install
your own fixed point combinator for it to use, which looks like
your own fixed point combinator for it to use, which looks like
this,
this,
<lang Ursala>#fix my_fix</lang>
<syntaxhighlight lang="ursala">#fix my_fix</syntaxhighlight>
with your choice of function to be used in place of <code>my_fix</code>.
with your choice of function to be used in place of <code>my_fix</code>.
Having done that, you may express recursive functions per convention by circular definitions,
Having done that, you may express recursive functions per convention by circular definitions,
as in this example of a Fibonacci function.
as in this example of a Fibonacci function.
<lang Ursala>fib = {0,1}?</1! sum+ fib~~+ predecessor^~/~& predecessor</lang>
<syntaxhighlight lang="ursala">fib = {0,1}?</1! sum+ fib~~+ predecessor^~/~& predecessor</syntaxhighlight>
Note that this way is only syntactic sugar for the for explicit way
Note that this way is only syntactic sugar for the for explicit way
shown above. Without a fixed point combinator given in the <code>#fix</code>
shown above. Without a fixed point combinator given in the <code>#fix</code>
Line 5,295: Line 5,295:
To confirm that all this works, here is a test program applying
To confirm that all this works, here is a test program applying
both of the functions defined above to the numbers from 1 to 8.
both of the functions defined above to the numbers from 1 to 8.
<lang Ursala>#cast %nLW
<syntaxhighlight lang="ursala">#cast %nLW


examples = (fact* <1,2,3,4,5,6,7,8>,fib* <1,2,3,4,5,6,7,8>)</lang>
examples = (fact* <1,2,3,4,5,6,7,8>,fib* <1,2,3,4,5,6,7,8>)</syntaxhighlight>
{{out}}
{{out}}
<pre>
<pre>
Line 5,312: Line 5,312:
(with 0 signifying the lowest order of fixed point combinators),
(with 0 signifying the lowest order of fixed point combinators),
or if that's too easy, then by this definition.
or if that's too easy, then by this definition.
<lang Ursala>#import sol
<syntaxhighlight lang="ursala">#import sol


#fix general_function_fixer 1
#fix general_function_fixer 1


my_fix "h" = "h" my_fix "h"</lang>
my_fix "h" = "h" my_fix "h"</syntaxhighlight>
Note that this equation is solved using the next fixed point combinator in the hierarchy.
Note that this equation is solved using the next fixed point combinator in the hierarchy.


Line 5,322: Line 5,322:
{{trans|Phix}}
{{trans|Phix}}
The IIf as translation of Iff can not be used as IIf executes both true and false parts and will cause a stack overflow.
The IIf as translation of Iff can not be used as IIf executes both true and false parts and will cause a stack overflow.
<lang vb>Private Function call_fn(f As String, n As Long) As Long
<syntaxhighlight lang="vb">Private Function call_fn(f As String, n As Long) As Long
call_fn = Application.Run(f, f, n)
call_fn = Application.Run(f, f, n)
End Function
End Function
Line 5,359: Line 5,359:
test "fac"
test "fac"
test "fib"
test "fib"
End Sub</lang>{{out}}
End Sub</syntaxhighlight>{{out}}
<pre>fac
<pre>fac
1 2 6 24 120 720 5040 40320 362880 3628800
1 2 6 24 120 720 5040 40320 362880 3628800
Line 5,366: Line 5,366:


=={{header|Verbexx}}==
=={{header|Verbexx}}==
<lang verbexx>/////// Y-combinator function (for single-argument lambdas) ///////
<syntaxhighlight lang="verbexx">/////// Y-combinator function (for single-argument lambdas) ///////


y @FN [f]
y @FN [f]
Line 5,400: Line 5,400:


@LOOP init:{ i = -1} while:(i <= 16) next:{i++}
@LOOP init:{ i = -1} while:(i <= 16) next:{i++}
{ @SAY "fibonacci<" i "> =" (@fibonacci i) };</lang>
{ @SAY "fibonacci<" i "> =" (@fibonacci i) };</syntaxhighlight>


=={{header|Vim Script}}==
=={{header|Vim Script}}==
There is no lambda in Vim (yet?), so here is a way to fake it using a Dictionary. This also provides garbage collection.
There is no lambda in Vim (yet?), so here is a way to fake it using a Dictionary. This also provides garbage collection.
<lang vim>" Translated from Python. Works with: Vim 7.0
<syntaxhighlight lang="vim">" Translated from Python. Works with: Vim 7.0


func! Lambx(sig, expr, dict)
func! Lambx(sig, expr, dict)
Line 5,426: Line 5,426:
echo Callx(Callx(g:Y, [g:fac]), [5])
echo Callx(Callx(g:Y, [g:fac]), [5])
echo map(range(10), 'Callx(Callx(Y, [fac]), [v:val])')
echo map(range(10), 'Callx(Callx(Y, [fac]), [v:val])')
</syntaxhighlight>
</lang>
Update: since Vim 7.4.2044 (or so...), the following can be used (the feature check was added with 7.4.2121):
Update: since Vim 7.4.2044 (or so...), the following can be used (the feature check was added with 7.4.2121):
<lang vim>
<syntaxhighlight lang="vim">
if !has("lambda")
if !has("lambda")
echoerr 'Lambda feature required'
echoerr 'Lambda feature required'
Line 5,438: Line 5,438:
echo Y(Fac)(5)
echo Y(Fac)(5)
echo map(range(10), 'Y(Fac)(v:val)')
echo map(range(10), 'Y(Fac)(v:val)')
</syntaxhighlight>
</lang>
Output:
Output:
<pre>120
<pre>120
Line 5,444: Line 5,444:


=={{header|Wart}}==
=={{header|Wart}}==
<lang python># Better names due to Jim Weirich: http://vimeo.com/45140590
<syntaxhighlight lang="python"># Better names due to Jim Weirich: http://vimeo.com/45140590
def (Y improver)
def (Y improver)
((fn(gen) gen.gen)
((fn(gen) gen.gen)
Line 5,457: Line 5,457:
(n * (f n-1))))))
(n * (f n-1))))))


prn factorial.5</lang>
prn factorial.5</syntaxhighlight>


{{omit from|ACL2}}
{{omit from|ACL2}}
Line 5,466: Line 5,466:
=={{header|Wren}}==
=={{header|Wren}}==
{{trans|Go}}
{{trans|Go}}
<lang ecmascript>var y = Fn.new { |f|
<syntaxhighlight lang="ecmascript">var y = Fn.new { |f|
var g = Fn.new { |r| f.call { |x| r.call(r).call(x) } }
var g = Fn.new { |r| f.call { |x| r.call(r).call(x) } }
return g.call(g)
return g.call(g)
Line 5,479: Line 5,479:


System.print("fac(10) = %(fac.call(10))")
System.print("fac(10) = %(fac.call(10))")
System.print("fib(10) = %(fib.call(10))")</lang>
System.print("fib(10) = %(fib.call(10))")</syntaxhighlight>


{{out}}
{{out}}
Line 5,491: Line 5,491:
Version 3.0 of the [http://www.w3.org/TR/xpath-30/ XPath] and [http://www.w3.org/TR/xquery-30/ XQuery] specifications added support for function items.
Version 3.0 of the [http://www.w3.org/TR/xpath-30/ XPath] and [http://www.w3.org/TR/xquery-30/ XQuery] specifications added support for function items.


<lang XQuery>let $Y := function($f) {
<syntaxhighlight lang="xquery">let $Y := function($f) {
(function($x) { ($x)($x) })( function($g) { $f( (function($a) { $g($g) ($a)}) ) } )
(function($x) { ($x)($x) })( function($g) { $f( (function($a) { $g($g) ($a)}) ) } )
}
}
Line 5,500: Line 5,500:
$fib(6)
$fib(6)
)
)
</syntaxhighlight>
</lang>
{{out}}
{{out}}
<lang XQuery>720 8</lang>
<syntaxhighlight lang="xquery">720 8</syntaxhighlight>


=={{header|Yabasic}}==
=={{header|Yabasic}}==
<lang Yabasic>sub fac(self$, n)
<syntaxhighlight lang="yabasic">sub fac(self$, n)
if n > 1 then
if n > 1 then
return n * execute(self$, self$, n - 1)
return n * execute(self$, self$, n - 1)
Line 5,532: Line 5,532:


test("fac")
test("fac")
test("fib")</lang>
test("fib")</syntaxhighlight>


=={{header|zkl}}==
=={{header|zkl}}==
<lang zkl>fcn Y(f){ fcn(g){ g(g) }( 'wrap(h){ f( 'wrap(a){ h(h)(a) }) }) }</lang>
<syntaxhighlight lang="zkl">fcn Y(f){ fcn(g){ g(g) }( 'wrap(h){ f( 'wrap(a){ h(h)(a) }) }) }</syntaxhighlight>
Functions don't get to look outside of their scope so data in enclosing scopes needs to be bound to a function, the fp (function application/cheap currying) method does this. 'wrap is syntactic sugar for fp.
Functions don't get to look outside of their scope so data in enclosing scopes needs to be bound to a function, the fp (function application/cheap currying) method does this. 'wrap is syntactic sugar for fp.
<lang zkl>fcn almost_factorial(f){ fcn(n,f){ if(n<=1) 1 else n*f(n-1) }.fp1(f) }
<syntaxhighlight lang="zkl">fcn almost_factorial(f){ fcn(n,f){ if(n<=1) 1 else n*f(n-1) }.fp1(f) }
Y(almost_factorial)(6).println();
Y(almost_factorial)(6).println();
[0..10].apply(Y(almost_factorial)).println();</lang>
[0..10].apply(Y(almost_factorial)).println();</syntaxhighlight>
{{out}}
{{out}}
<pre>
<pre>
Line 5,545: Line 5,545:
L(1,1,2,6,24,120,720,5040,40320,362880,3628800)
L(1,1,2,6,24,120,720,5040,40320,362880,3628800)
</pre>
</pre>
<lang zkl>fcn almost_fib(f){ fcn(n,f){ if(n<2) 1 else f(n-1)+f(n-2) }.fp1(f) }
<syntaxhighlight lang="zkl">fcn almost_fib(f){ fcn(n,f){ if(n<2) 1 else f(n-1)+f(n-2) }.fp1(f) }
Y(almost_fib)(9).println();
Y(almost_fib)(9).println();
[0..10].apply(Y(almost_fib)).println();</lang>
[0..10].apply(Y(almost_fib)).println();</syntaxhighlight>
{{out}}
{{out}}
<pre>
<pre>