Y combinator: Difference between revisions

37,199 bytes added ,  2 months ago
m
m (→‎{{header|Rust}}: Fixed some more deprecated trait objects)
 
(82 intermediate revisions by 36 users not shown)
Line 4:
 
In strict [[wp:Functional programming|functional programming]] and the [[wp:lambda calculus|lambda calculus]], functions (lambda expressions) don't have state and are only allowed to refer to arguments of enclosing functions.
 
This rules out the usual definition of a recursive function wherein a function is associated with the state of a variable and this variable's state is used in the body of the function.
 
The   [http://mvanier.livejournal.com/2897.html Y combinator]   is itself a stateless function that, when applied to another stateless function, returns a recursive version of the function. The Y combinator is the simplest of the class of such functions, called [[wp:Fixed-point combinator|fixed-point combinators]].
 
The Y combinator is the simplest of the class of such functions, called [[wp:Fixed-point combinator|fixed-point combinators]].
 
 
;Task:
Define the stateless   ''Y combinator''   and use it to compute [[wp:Factorial|factorials]] and [[wp:Fibonacci number|Fibonacci numbers]] from other stateless functions or lambda expressions.
 
 
Line 19 ⟶ 22:
=={{header|AArch64 Assembly}}==
{{works with|as|Raspberry Pi 3B version Buster 64 bits}}
<syntaxhighlight lang="aarch64 assembly">
<lang AArch64 Assembly>
/* ARM assembly AARCH64 Raspberry PI 3B */
/* program Ycombi64.s */
Line 284 ⟶ 287:
/* for this file see task include a file in language AArch64 assembly */
.include "../includeARM64.inc"
</syntaxhighlight>
</lang>
 
=={{header|ALGOL 68}}==
Line 293 ⟶ 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|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}} -->
<langsyntaxhighlight lang="algol68">BEGIN
MODE F = PROC(INT)INT;
MODE Y = PROC(Y)F;
Line 303 ⟶ 306:
 
FOR i TO 10 DO print(y(fib)(i)) OD
END</langsyntaxhighlight>
<!--
ALGOL 68G Output demonstrating the runtime scope violation:
Line 312 ⟶ 315:
</pre>
-->
 
 
 
The version below works with [[ALGOL 68 Genie]] 3.5.0 tested with Linux kernel release 6.7.4-200.fc39.x86_64
 
N.B. 4 warnings are issued of the form
<br>
a68g: warning: 1: declaration hides a declaration of "..." with larger reach, in closed-clause starting at "(" in line dd.
<br>
These could easily be fixed by changing names, but I believe that doing so would make the code harder to follow.
 
<syntaxhighlight>BEGIN
 
# This version needs partial parameterisation in order to work #
# The commented code is JavaScript aka ECMAScript ES6 #
 
 
MODE F = PROC( INT ) INT ;
MODE X = PROC( X ) F ;
 
 
#
Y_combinator =
func_gen => ( x => x( x ) )( x => func_gen( arg => x( x )( arg ) ) )
#
 
PROC y combinator = ( PROC( F ) F func gen ) F:
( ( X x ) F: x( x ) )
(
(
( PROC( F ) F func gen , X x ) F:
func gen( ( ( X x , INT arg ) INT: x( x )( arg ) )( x , ) )
)( func gen , )
)
;
 
 
#
fac_gen = fac => (n => ( ( n === 0 ) ? 1 : n * fac( n - 1 ) ) )
#
 
PROC fac gen = ( F fac ) F:
( ( F fac , INT n ) INT: IF n = 0 THEN 1 ELSE n * fac( n - 1 ) FI )( fac , )
;
 
 
#
factorial = Y_combinator( fac_gen )
#
 
F factorial = y combinator( fac gen ) ;
 
 
#
fib_gen =
fib =>
( n => ( ( n === 0 ) ? 0 : ( n === 1 ) ? 1 : fib( n - 2 ) + fib( n - 1 ) ) )
#
 
PROC fib gen = ( F fib ) F:
(
( F fib , INT n ) INT:
CASE n + 1 IN 0 , 1 OUT fib( n - 2 ) + fib( n - 1 ) ESAC
)( fib , )
;
 
 
#
fibonacci = Y_combinator( fib_gen )
#
 
F fibonacci = y combinator( fib gen ) ;
 
 
#
for ( i = 1 ; i <= 12 ; i++) { process.stdout.write( " " + factorial( i ) ) }
#
 
INT nofacs = 12 ;
printf( ( $ l , "Here are the first " , g( 0 ) , " factorials." , l $ , nofacs ) ) ;
FOR i TO nofacs
DO
printf( ( $ " " , g( 0 ) $ , factorial( i ) ) )
OD ;
print( newline ) ;
 
 
#
for ( i = 1 ; i <= 12 ; i++) { process.stdout.write( " " + fibonacci( i ) ) }
#
 
INT nofibs = 12 ;
printf( (
$ l , "Here are the first " , g( 0 ) , " fibonacci numbers." , l $
, nofibs
) )
;
FOR i TO nofibs
DO
printf( ( $ " " , g( 0 ) $ , fibonacci( i ) ) )
OD ;
print( newline )
 
END</syntaxhighlight>
 
=={{header|AppleScript}}==
Line 321 ⟶ 428:
 
The identifier used for Y uses "pipe quoting" to make it obviously distinct from the y used inside the definition.
<langsyntaxhighlight AppleScriptlang="applescript">-- Y COMBINATOR ---------------------------------------------------------------
 
on |Y|(f)
Line 417 ⟶ 524:
end script
end if
end mReturn</langsyntaxhighlight>
{{Out}}
<langsyntaxhighlight AppleScriptlang="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}}</langsyntaxhighlight>
 
=={{header|ARM Assembly}}==
{{works with|as|Raspberry Pi}}
<syntaxhighlight lang="arm assembly">
<lang ARM Assembly>
 
/* ARM assembly Raspberry PI */
Line 677 ⟶ 784:
.include "../affichage.inc"
 
</syntaxhighlight>
</lang>
{{output}}
<pre>
Line 707 ⟶ 814:
 
=={{header|ATS}}==
<syntaxhighlight lang="ats">
<lang ATS>
(* ****** ****** *)
//
Line 732 ⟶ 839:
//
(* ****** ****** *)
</syntaxhighlight>
</lang>
 
=={{header|BASIC}}==
==={{header|FreeBASIC}}===
FreeBASIC does not support nested functions, lambda expressions or functions inside nested types
<syntaxhighlight lang="freebasic">Function Y(f As String) As String
Y = f
End Function
 
Function fib(n As Long) As Long
Dim As Long n1 = 0, n2 = 1, k, sum
For k = 1 To Abs(n)
sum = n1 + n2
n1 = n2
n2 = sum
Next k
Return Iif(n < 0, (n1 * ((-1) ^ ((-n)+1))), n1)
End Function
 
Function fac(n As Long) As Long
Dim As Long r = 1, i
For i = 2 To n
r *= i
Next i
Return r
End Function
 
Function execute(s As String, n As Integer) As Long
Return Iif (s = "fac", fac(n), fib(n))
End Function
 
Sub test(nombre As String)
Dim f As String: f = Y(nombre)
Print !"\n"; f; ":";
For i As Integer = 1 To 10
Print execute(f, i);
Next i
End Sub
 
test("fac")
test("fib")
Sleep</syntaxhighlight>
{{out}}
<pre>fac: 1 2 6 24 120 720 5040 40320 362880 3628800
fib: 1 1 2 3 5 8 13 21 34 55</pre>
 
==={{header|VBA}}===
{{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.
<syntaxhighlight lang="vb">Private Function call_fn(f As String, n As Long) As Long
call_fn = Application.Run(f, f, n)
End Function
Private Function Y(f As String) As String
Y = f
End Function
Private Function fac(self As String, n As Long) As Long
If n > 1 Then
fac = n * call_fn(self, n - 1)
Else
fac = 1
End If
End Function
Private Function fib(self As String, n As Long) As Long
If n > 1 Then
fib = call_fn(self, n - 1) + call_fn(self, n - 2)
Else
fib = n
End If
End Function
Private Sub test(name As String)
Dim f As String: f = Y(name)
Dim i As Long
Debug.Print name
For i = 1 To 10
Debug.Print call_fn(f, i);
Next i
Debug.Print
End Sub
 
Public Sub main()
test "fac"
test "fib"
End Sub</syntaxhighlight>{{out}}
<pre>fac
1 2 6 24 120 720 5040 40320 362880 3628800
fib
1 1 2 3 5 8 13 21 34 55 </pre>
 
==={{header|uBasic/4tH}}===
{{Trans|Yabasic}}
<syntaxhighlight lang="basic">Proc _Test("fac")
Proc _Test("fib")
End
 
_fac
Param (2)
If b@ > 1 Then Return (b@ * FUNC (a@ (a@, b@-1)))
Return (1)
 
_fib
Param (2)
If b@ > 1 Then Return (FUNC (a@ (a@, b@-1)) + FUNC (a@ (a@, b@-2)))
Return (b@)
_Test
Param (1)
Local (1)
Print Show (a@), ": "; : a@ = Name (a@)
For b@ = 1 to 10 : Print FUNC (a@ (a@, b@)), : Next : Print
Return</syntaxhighlight>
{{Out}}
<pre>fac : 1 2 6 24 120 720 5040 40320 362880 3628800
fib : 1 1 2 3 5 8 13 21 34 55
 
0 OK, 0:39 </pre>
==={{header|Yabasic}}===
<syntaxhighlight lang="yabasic">sub fac(self$, n)
if n > 1 then
return n * execute(self$, self$, n - 1)
else
return 1
end if
end sub
sub fib(self$, n)
if n > 1 then
return execute(self$, self$, n - 1) + execute(self$, self$, n - 2)
else
return n
end if
end sub
sub test(name$)
local i
print name$, ": ";
for i = 1 to 10
print execute(name$, name$, i);
next
print
end sub
 
test("fac")
test("fib")</syntaxhighlight>
 
=={{header|Binary Lambda Calculus}}==
This BLC program outputs 6!, as computed with the Y combinator, in unary (generated from https://github.com/tromp/AIT/blob/master/rosetta/facY.lam) :
 
<pre>11 c2 a3 40 b0 bf 65 ee 05 7c 0c ef 18 89 70 39 d0 39 ce 81 6e c0 3c e8 31</pre>
 
=={{header|BlitzMax}}==
BlitzMax doesn't support anonymous functions or classes, so everything needs to be explicitly named.
<langsyntaxhighlight lang="blitzmax">SuperStrict
 
'Boxed type so we can just use object arrays for argument lists
Line 891 ⟶ 1,151:
 
Local fib:Func = Func(_Y.apply([FibL1.lambda(Null)]))
Print Integer(fib.apply([Integer.Make(10)])).val</langsyntaxhighlight>
 
=={{header|Bracmat}}==
Line 909 ⟶ 1,169:
<pre>(Y H) i</pre>
where i varies between 1 and 10, are translated into Bracmat as shown below
<langsyntaxhighlight lang="bracmat">( ( Y
= /(
' ( g
Line 952 ⟶ 1,212:
)
&
)</langsyntaxhighlight>
{{out}}
<pre>1!=1
Line 974 ⟶ 1,234:
fib(9)=34
fib(10)=55</pre>
 
=={{header|Bruijn}}==
As defined in <code>std/Combinator</code>:
<syntaxhighlight lang="bruijn">
:import std/Number .
 
# sage bird combinator
y [[1 (0 0)] [1 (0 0)]]
 
# factorial using y
factorial y [[=?0 (+1) (0 ⋅ (1 --0))]]
 
:test ((factorial (+6)) =? (+720)) ([[1]])
 
# (very slow) fibonacci using y
fibonacci y [[0 <? (+1) (+0) (0 <? (+2) (+1) rec)]]
rec (1 --0) + (1 --(--0))
 
:test ((fibonacci (+6)) =? (+8)) ([[1]])
</syntaxhighlight>
 
=={{header|C}}==
C doesn't have first class functions, so we demote everything to second class to match.<langsyntaxhighlight Clang="c">#include <stdio.h>
#include <stdlib.h>
 
Line 1,046 ⟶ 1,326:
return 0;
}
</syntaxhighlight>
</lang>
 
{{out}}
Line 1,060 ⟶ 1,340:
''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.''
 
<langsyntaxhighlight lang="csharp">using System;
 
static class YCombinator<T, TResult>
Line 1,082 ⟶ 1,362:
}
}
</syntaxhighlight>
</lang>
{{out}}
<pre>3628800
Line 1,088 ⟶ 1,368:
 
Alternatively, with a non-generic holder class (note that <code>Fix</code> is now a method, as properties cannot be generic):
<langsyntaxhighlight lang="csharp">static class YCombinator
{
private delegate Func<T, TResult> RecursiveFunc<T, TResult>(RecursiveFunc<T, TResult> r);
Line 1,094 ⟶ 1,374:
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)));
}</langsyntaxhighlight>
 
Using the late-binding offered by <code>dynamic</code> to eliminate the recursive type:
<langsyntaxhighlight lang="csharp">static class YCombinator<T, TResult>
{
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))));
}</langsyntaxhighlight>
 
The usual version using recursion, disallowed by the task (implemented as a generic method):
<langsyntaxhighlight 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);
}</langsyntaxhighlight>
 
===Translations===
Line 1,116 ⟶ 1,396:
 
'''Verbatim'''
<langsyntaxhighlight lang="csharp">using Func = System.Func<int, int>;
using FuncFunc = System.Func<System.Func<int, int>, System.Func<int, int>>;
 
Line 1,156 ⟶ 1,436:
return 0;
}
}</langsyntaxhighlight>
 
'''Semi-idiomatic'''
<langsyntaxhighlight lang="csharp">using System;
 
using FuncFunc = System.Func<System.Func<int, int>, System.Func<int, int>>;
Line 1,185 ⟶ 1,465:
Console.WriteLine("fac(10) = " + fac(10));
}
}</langsyntaxhighlight>
 
====[http://rosettacode.org/mw/index.php?oldid=287744#Ceylon Ceylon]====
Line 1,193 ⟶ 1,473:
 
'''Verbatim'''
<langsyntaxhighlight lang="csharp">using System;
using System.Diagnostics;
 
Line 1,240 ⟶ 1,520:
Console.WriteLine(fibY1(10)); // 110
}
}</langsyntaxhighlight>
 
'''Semi-idiomatic'''
<langsyntaxhighlight lang="csharp">using System;
using System.Diagnostics;
 
Line 1,286 ⟶ 1,566:
Console.WriteLine(fibY1(10));
}
}</langsyntaxhighlight>
 
====[http://rosettacode.org/mw/index.php?oldid=287744#Go Go]====
Line 1,292 ⟶ 1,572:
 
'''Verbatim'''
<langsyntaxhighlight 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.
Line 1,334 ⟶ 1,614:
};
}
}</langsyntaxhighlight>
 
Recursive:
<langsyntaxhighlight lang="csharp"> static Func Y(FuncFunc f) {
return delegate (int x) {
return f(Y(f))(x);
};
}</langsyntaxhighlight>
 
'''Semi-idiomatic'''
<langsyntaxhighlight lang="csharp">using System;
 
delegate int Func(int i);
Line 1,366 ⟶ 1,646:
 
static Func almost_fib(Func f) => x => x <= 2 ? 1 : f(x - 1) + f(x - 2);
}</langsyntaxhighlight>
 
Recursive:
<langsyntaxhighlight lang="csharp"> static Func Y(FuncFunc f) => x => f(Y(f))(x);</langsyntaxhighlight>
 
====[http://rosettacode.org/mw/index.php?oldid=287744#Java Java]====
Line 1,376 ⟶ 1,656:
 
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.
<langsyntaxhighlight lang="csharp">using System;
 
static class Program {
Line 1,424 ⟶ 1,704:
Console.WriteLine("fac(10) = " + fac.apply(10));
}
}</langsyntaxhighlight>
 
'''"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].
<langsyntaxhighlight lang="csharp">using System;
 
static class YCombinator {
Line 1,519 ⟶ 1,799:
Console.WriteLine("fac(10) = " + fac.apply(10));
}
}</langsyntaxhighlight>
 
'''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.
<langsyntaxhighlight lang="csharp">using System;
 
class Program {
Line 1,620 ⟶ 1,900:
Console.WriteLine("fac(10) = " + fac.apply(10));
}
}</langsyntaxhighlight>
 
'''Modified/varargs (the last implementation in the Java section)'''
Line 1,626 ⟶ 1,906:
Since C# delegates cannot declare members, extension methods are used to simulate doing so.
 
<langsyntaxhighlight lang="csharp">using System;
using System.Collections.Generic;
using System.Linq;
Line 1,754 ⟶ 2,034:
).ForAll(Console.WriteLine);
}
}</langsyntaxhighlight>
 
====[http://rosettacode.org/mw/index.php?oldid=287744#Swift Swift]====
Line 1,762 ⟶ 2,042:
 
The more idiomatic version doesn't look much different.
<langsyntaxhighlight lang="csharp">using System;
 
static class Program {
Line 1,782 ⟶ 2,062:
Console.WriteLine($"fib(9) = {fib(9)}");
}
}</langsyntaxhighlight>
 
Without recursive type:
<langsyntaxhighlight 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)); };
return r(r);
}</langsyntaxhighlight>
 
Recursive:
<langsyntaxhighlight lang="csharp"> public static Func<In, Out> Y<In, Out>(Func<Func<In, Out>, Func<In, Out>> f) {
return x => f(Y(f))(x);
}</langsyntaxhighlight>
 
=={{header|C++}}==
Line 1,799 ⟶ 2,079:
Known to work with GCC 4.7.2. Compile with
g++ --std=c++11 ycomb.cc
<langsyntaxhighlight lang="cpp">#include <iostream>
#include <functional>
 
Line 1,841 ⟶ 2,121:
std::cout << "fac(10) = " << fac(10) << std::endl;
return 0;
}</langsyntaxhighlight>
{{out}}
 
Line 1,852 ⟶ 2,132:
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
<langsyntaxhighlight lang="cpp">#include <iostream>
#include <functional>
int main () {
Line 1,863 ⟶ 2,143:
auto almost_fib = [] (auto f) { return
[=] (auto n) { return
n < 2? n1: f (n - 1) + f (n - 2) ;};};
auto almost_fac = [] (auto f) { return
[=] (auto n) { return
Line 1,872 ⟶ 2,152:
std:: cout << fib (10) << '\n'
<< fac (10) << '\n';
}</langsyntaxhighlight>
{{out}}
 
Line 1,881 ⟶ 2,161:
 
The usual version using recursion, disallowed by the task:
<langsyntaxhighlight lang="cpp">template <typename A, typename B>
std::function<B(A)> Y (std::function<std::function<B(A)>(std::function<B(A)>)> f) {
return [f](A x) {
return f(Y(f))(x);
};
}</langsyntaxhighlight>
 
Another version which is disallowed because a function passes itself, which is also a kind of recursion:
<langsyntaxhighlight lang="cpp">template <typename A, typename B>
struct YFunctor {
const std::function<std::function<B(A)>(std::function<B(A)>)> f;
Line 1,901 ⟶ 2,181:
std::function<B(A)> Y (std::function<std::function<B(A)>(std::function<B(A)>)> f) {
return YFunctor<A,B>(f);
}</langsyntaxhighlight>
 
=={{header|Ceylon}}==
Using a class for the recursive type:
<langsyntaxhighlight lang="ceylon">Result(*Args) y1<Result,Args>(
Result(*Args)(Result(*Args)) f)
given Args satisfies Anything[] {
Line 1,926 ⟶ 2,206:
 
print(factorialY1(10)); // 3628800
print(fibY1(10)); // 110</langsyntaxhighlight>
 
Using Anything to erase the function type:
<langsyntaxhighlight lang="ceylon">Result(*Args) y2<Result,Args>(
Result(*Args)(Result(*Args)) f)
given Args satisfies Anything[] {
Line 1,939 ⟶ 2,219:
 
return r(r);
}</langsyntaxhighlight>
 
Using recursion, this does not satisfy the task requirements, but is included here for illustrative purposes:
<langsyntaxhighlight lang="ceylon">Result(*Args) y3<Result, Args>(
Result(*Args)(Result(*Args)) f)
given Args satisfies Anything[]
=> flatten((Args args) => f(y3(f))(*args));</langsyntaxhighlight>
 
=={{header|Chapel}}==
 
Strict (non-lazy = non-deferred execution) languages will race with the usually defined Y combinator (call-by-name) so most implementations are the Z combinator which lack one Beta Reduction from the true Y combinator (they are call-by-value). Although one can inject laziness so as to make the true Y combinator work with strict languages, the following code implements the usual Z call-by-value combinator using records to represent closures as Chapel does not have First Class Functions that can capture bindings from outside their scope other than from global scope:
 
{{works with|Chapel version 1.24.1}}
<syntaxhighlight lang="chapel">proc fixz(f) {
record InnerFunc {
const xi;
proc this(a) { return xi(xi)(a); }
}
record XFunc {
const fi;
proc this(x) { return fi(new InnerFunc(x)); }
}
const g = new XFunc(f);
return g(g);
}
 
record Facz {
record FacFunc {
const fi;
proc this(n: int): int {
return if n <= 1 then 1 else n * fi(n - 1); }
}
proc this(f) { return new FacFunc(f); }
}
 
record Fibz {
record FibFunc {
const fi;
proc this(n: int): int {
return if n <= 1 then n else fi(n - 2) + fi(n - 1); }
}
proc this(f) { return new FibFunc(f); }
}
 
const facz = fixz(new Facz());
const fibz = fixz(new Fibz());
 
writeln(facz(10));
writeln(fibz(10));</syntaxhighlight>
{{out}}
<pre>3628800
55</pre>
 
One can write a true call-by-name Y combinator by injecting one level of laziness or deferred execution at the defining function level as per the following code:
 
{{works with|Chapel version 1.24.1}}
<syntaxhighlight lang="chapel">// this is the longer version...
/*
proc fixy(f) {
record InnerFunc {
const xi;
proc this() { return xi(xi); }
}
record XFunc {
const fi;
proc this(x) { return fi(new InnerFunc(x)); }
}
const g = new XFunc(f);
return g(g);
}
// */
 
// short version using direct recursion as Chapel has...
// 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,
// instead of the function that uses it...
proc fixy(f) {
record InnerFunc { const fi; proc this() { return fixy(fi); } }
return f(new InnerFunc(f));
}
 
record Facy {
record FacFunc {
const fi;
proc this(n: int): int {
return if n <= 1 then 1 else n * fi()(n - 1); }
}
proc this(f) { return new FacFunc(f); }
}
 
record Fiby {
record FibFunc {
const fi;
proc this(n: int): int {
return if n <= 1 then n else fi()(n - 2) + fi()(n - 1); }
}
proc this(f) { return new FibFunc(f); }
}
 
const facy = fixy(new Facy());
const fibz = fixy(new Fiby());
 
writeln(facy(10));
writeln(fibz(10));</syntaxhighlight>
The output is the same as the above.
 
=={{header|Clojure}}==
<langsyntaxhighlight lang="lisp">(defn Y [f]
((fn [x] (x x))
(fn [x]
Line 1,966 ⟶ 2,344:
1 1
(+ (f (dec n))
(f (dec (dec n))))))))</langsyntaxhighlight>
 
{{out}}
Line 1,976 ⟶ 2,354:
<code>Y</code> can be written slightly more concisely via syntax sugar:
 
<langsyntaxhighlight lang="lisp">(defn Y [f]
(#(% %) #(f (fn [& args] (apply (% %) args)))))</langsyntaxhighlight>
 
=={{header|CoffeeScript}}==
<langsyntaxhighlight lang="coffeescript">Y = (f) -> g = f( (t...) -> g(t...) )</langsyntaxhighlight>
or
<langsyntaxhighlight lang="coffeescript">Y = (f) -> ((h)->h(h))((h)->f((t...)->h(h)(t...)))</langsyntaxhighlight>
<langsyntaxhighlight 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 )
</syntaxhighlight>
</lang>
 
=={{header|Common Lisp}}==
<langsyntaxhighlight lang="lisp">(defun Y (f)
((lambda (g) (funcall g g))
(lambda (g)
Line 2,016 ⟶ 2,394:
 
? (mapcar #'fib '(1 2 3 4 5 6 7 8 9 10))
(1 1 2 3 5 8 13 21 34 55)</langsyntaxhighlight>
 
=={{header|Crystal}}==
 
Although Crystal is very much an OOP language, it does have "Proc"'s that can be used as lambda functions and even as closures where they capture state from the environment external to the body, and these can be used to implement the Y-Combinator. Note that many of the other static strict languages don't implement the true Y-Combinator but rather the Z-Combinator, which lacks one Beta reduction from the Y-Combinator and is more limiting in use. For strict languages such as Crystal, all that is needed to implement the true Y-Combinator is to inject some laziness by deferring execution using a "Thunk" - a function without any arguments returning a deferred value, which requires that functions can also be closures.
 
The following Crystal code implements the name-recursion Y-Combinator without assuming that functions are recursive (which in Crystal they actually are):
 
<syntaxhighlight lang="crystal">require "big"
 
struct RecursiveFunc(T) # a generic recursive function wrapper...
getter recfnc : RecursiveFunc(T) -> T
def initialize(@recfnc) end
end
 
struct YCombo(T) # a struct or class needs to be used so as to be generic...
def initialize (@fnc : Proc(T) -> T) end
def fixy
g = -> (x : RecursiveFunc(T)) {
@fnc.call(-> { x.recfnc.call(x) }) }
g.call(RecursiveFunc(T).new(g))
end
end
 
def fac(x) # horrendouly inefficient not using tail calls...
facp = -> (fn : Proc(BigInt -> BigInt)) {
-> (n : BigInt) { n < 2 ? n : n * fn.call.call(n - 1) } }
YCombo.new(facp).fixy.call(BigInt.new(x))
end
 
def fib(x) # horrendouly inefficient not using tail calls...
facp = -> (fn : Proc(BigInt -> BigInt)) {
-> (n : BigInt) {
n < 3 ? n - 1 : fn.call.call(n - 2) + fn.call.call(n - 1) } }
YCombo.new(facp).fixy.call(BigInt.new(x))
end
 
puts fac(10)
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:
 
<syntaxhighlight lang="crystal">def fac(x) # the more efficient tail recursive version...
facp = -> (fn : Proc(BigInt -> (Int32 -> BigInt))) {
-> (n : BigInt) { -> (i : Int32) {
i < 2 ? n : fn.call.call(i * n).call(i - 1) } } }
YCombo.new(facp).fixy.call(BigInt.new(1)).call(x)
end
 
def fib(x) # the more efficient tail recursive version...
fibp = -> (fn : Proc(BigInt -> (BigInt -> (Int32 -> BigInt)))) {
-> (f : BigInt) { -> (s : BigInt) { -> (i : Int32) {
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)
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:
 
<syntaxhighlight lang="crystal">def ycombo(f)
f.call(-> { ycombo(f) })
end
 
def fac(x) # the more efficient tail recursive version...
facp = -> (fn : Proc(BigInt -> (Int32 -> BigInt))) {
-> (n : BigInt) { -> (i : Int32) {
i < 2 ? n : fn.call.call(i * n).call(i - 1) } } }
ycombo(facp).call(BigInt.new(1)).call(x)
end
 
def fib(x) # the more efficient tail recursive version...
fibp = -> (fn : Proc(BigInt -> (BigInt -> (Int32 -> BigInt)))) {
-> (f : BigInt) { -> (s : BigInt) { -> (i : Int32) {
i < 2 ? f : fn.call.call(s).call(f + s).call(i - 1) } } } }
ycombo(fibp).call(BigInt.new).call(BigInt.new(1)).call(x)
end</syntaxhighlight>
 
All versions produce the same output:
{{out}}
<pre>3628800
55</pre>
 
=={{header|D}}==
A stateless generic Y combinator:
<langsyntaxhighlight lang="d">import std.stdio, std.traits, std.algorithm, std.range;
 
auto Y(S, T...)(S delegate(T) delegate(S delegate(T)) f) {
Line 2,044 ⟶ 2,501:
writeln("factorial: ", 10.iota.map!factorial);
writeln("ackermann(3, 5): ", ackermann(3, 5));
}</langsyntaxhighlight>
{{out}}
<pre>factorial: [1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880]
Line 2,054 ⟶ 2,511:
{{trans|C++}}
(The translation is not literal; e.g. the function argument type is left unspecified to increase generality.)
<langsyntaxhighlight lang="delphi">program Y;
 
{$APPTYPE CONSOLE}
Line 2,120 ⟶ 2,577:
Writeln ('Fib(10) = ', Fib (10));
Writeln ('Fac(10) = ', Fac (10));
end.</langsyntaxhighlight>
 
=={{header|Dhall}}==
 
Dhall is not a turing complete language, so there's no way to implement the real Y combinator. That being said, you can replicate the effects of the Y combinator to any arbitrary but finite recursion depth using the builtin function Natural/Fold, which acts as a bounded fixed-point combinator that takes a natural argument to describe how far to recurse.
 
Here's an example using Natural/Fold to define recursive definitions of fibonacci and factorial:
 
<syntaxhighlight lang="dhall">let const
: ∀(b : Type) → ∀(a : Type) → a → b → a
= λ(r : Type) → λ(a : Type) → λ(x : a) → λ(y : r) → x
 
let fac
: ∀(n : Natural) → Natural
= λ(n : Natural) →
let factorial =
λ(f : Natural → Natural → Natural) →
λ(n : Natural) →
λ(i : Natural) →
if Natural/isZero i then n else f (i * n) (Natural/subtract 1 i)
 
in Natural/fold
n
(Natural → Natural → Natural)
factorial
(const Natural Natural)
1
n
 
let fib
: ∀(n : Natural) → Natural
= λ(n : Natural) →
let fibFunc = Natural → Natural → Natural → Natural
 
let fibonacci =
λ(f : fibFunc) →
λ(a : Natural) →
λ(b : Natural) →
λ(i : Natural) →
if Natural/isZero i
then a
else f b (a + b) (Natural/subtract 1 i)
 
in Natural/fold
n
fibFunc
fibonacci
(λ(a : Natural) → λ(_ : Natural) → λ(_ : Natural) → a)
0
1
n
 
in [fac 50, fib 50]</syntaxhighlight>
 
The above dhall file gets rendered down to:
 
<syntaxhighlight lang="dhall">[ 30414093201713378043612608166064768844377641568960512000000000000
, 12586269025
]</syntaxhighlight>
 
=={{header|Déjà Vu}}==
{{trans|Python}}
<langsyntaxhighlight lang="dejavu">Y f:
labda y:
labda:
Line 2,150 ⟶ 2,665:
 
!. fac 6
!. fib 6</langsyntaxhighlight>
{{out}}
<pre>720
Line 2,157 ⟶ 2,672:
=={{header|E}}==
{{trans|Python}}
<langsyntaxhighlight 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 fib := fn f { fn n { if (n == 0) {0} else if (n == 1) {1} else { f(n-1) + f(n-2) } }}</langsyntaxhighlight>
 
<langsyntaxhighlight lang="e">? pragma.enable("accumulator")
? accum [] for i in 0..!10 { _.with(y(fac)(i)) }
[1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880]
 
? accum [] for i in 0..!10 { _.with(y(fib)(i)) }
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34]</langsyntaxhighlight>
 
=={{header|EchoLisp}}==
<langsyntaxhighlight lang="scheme">
;; Ref : http://www.ece.uc.edu/~franco/C511/html/Scheme/ycomb.html
 
Line 2,193 ⟶ 2,708:
(fact 10)
→ 3628800
</syntaxhighlight>
</lang>
 
=={{header|Eero}}==
Translated from Objective-C example on this page.
<langsyntaxhighlight lang="objc">#import <Foundation/Foundation.h>
 
typedef int (^Func)(int)
Line 2,225 ⟶ 2,740:
Log('fac(10) = %d', fac(10))
 
return 0</langsyntaxhighlight>
 
=={{header|Ela}}==
<langsyntaxhighlight lang="ela">fix = \f -> (\x -> & f (x x)) (\x -> & f (x x))
 
fac _ 0 = 1
Line 2,237 ⟶ 2,752:
fib f n = f (n - 1) + f (n - 2)
 
(fix fac 12, fix fib 12)</langsyntaxhighlight>
 
{{out}}
Line 2,244 ⟶ 2,759:
=={{header|Elena}}==
{{trans|Smalltalk}}
ELENA 46.x :
<langsyntaxhighlight lang="elena">import extensions;
singleton YCombinator
Line 2,255 ⟶ 2,770:
public program()
{
var fib := YCombinator.fix::(f => (i => (i <= 1) ? i : (f(i-1) + f(i-2)) ));
var fact := YCombinator.fix::(f => (i => (i == 0) ? 1 : (f(i-1) * i) ));
console.printLine("fib(10)=",fib(10));
console.printLine("fact(10)=",fact(10));
}</langsyntaxhighlight>
{{out}}
<pre>
Line 2,269 ⟶ 2,784:
=={{header|Elixir}}==
{{trans|Python}}
<langsyntaxhighlight lang="elixir">
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>
Line 2,280 ⟶ 2,795:
iex(5)> for i <- 0..9, do: yc.(fib).(i)
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34]
</syntaxhighlight>
</lang>
 
=={{header|Elm}}==
 
This is similar to the Haskell solution below, but usesthe first `fixz` is a strict fixed-point combinator sincelacking one beta reduction as compared to the Y-combinator; the second `fixy` injects laziness using a "thunk" (a unit argument function whose return value is deferred until Elmthe lacksfunction lazyis evaluationcalled/applied).
 
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>
import Html exposing (text)
 
<syntaxhighlight lang="elm">module Main exposing ( main )
type Mu a b = Roll (Mu a b -> a -> b)
 
import Html exposing ( Html, text )
unroll : Mu a b -> (Mu a b -> a -> b)
unroll (Roll x) = x
-- As with most of the strict (non-deferred or non-lazy) languages,
-- this is the Z-combinator with the additional value parameter...
 
-- wrap type conversion to avoid recursive type definition...
fix : ((a -> b) -> (a -> b)) -> (a -> b)
fixtype fMu =a let g rb = fRoll (\vMu a b -> unrolla r r-> vb)
in g (Roll g)
unroll : Mu a b -> (Mu a b -> a -> b) -- unwrap it...
 
unroll (Roll x) = x
fac : Int -> Int
fac = fix <|
-- note lack of beta reduction using values...
\f n -> if n <= 0
fixz : ((a -> b) -> (a -> b)) -> (a -> then 1b)
fixz f = let g r = f (\ v -> unroll elser nr *v) fin (ng -(Roll 1g)
 
facz : Int -> Int
main = text <| toString <| fac 5
-- facz = fixz <| \ f n -> if n < 2 then 1 else n * f (n - 1) -- inefficient recursion
</lang>
facz = fixz (\ f n i -> if i < 2 then n else f (i * n) (i - 1)) 1 -- efficient tailcall
fibz : Int -> Int
-- fibz = fixz <| \ f n -> if n < 2 then n else f (n - 1) + f (n - 2) -- inefficient recursion
fibz = fixz (\ fn f s i -> if i < 2 then f else fn s (f + s) (i - 1)) 1 1 -- efficient tailcall
-- by injecting laziness, we can get the true Y-combinator...
-- as this includes laziness, there is no need for the type wrapper!
fixy : ((() -> a) -> a) -> a
fixy f = f <| \ () -> fixy f -- direct function recursion
-- the above is not value recursion but function recursion!
-- fixv f = let x = f x in x -- not allowed by task or by Elm!
-- we can make Elm allow it by injecting laziness...
-- fixv f = let x = f () x in x -- but now value recursion not function recursion
facy : Int -> Int
-- facy = fixy <| \ f n -> if n < 2 then 1 else n * f () (n - 1) -- inefficient recursion
facy = fixy (\ f n i -> if i < 2 then n else f () (i * n) (i - 1)) 1 -- efficient tailcall
fiby : Int -> Int
-- fiby = fixy <| \ f n -> if n < 2 then n else f () (n - 1) + f (n - 2) -- inefficient recursion
fiby = fixy (\ fn f s i -> if i < 2 then f else fn () s (f + s) (i - 1)) 1 1 -- efficient tailcall
-- something that can be done with a true Y-Combinator that
-- can't be done with the Z combinator...
-- given an infinite Co-Inductive Stream (CIS) defined as...
type CIS a = CIS a (() -> CIS a) -- infinite lazy stream!
mapCIS : (a -> b) -> CIS a -> CIS b -- uses function to map
mapCIS cf cis =
let mp (CIS head restf) = CIS (cf head) <| \ () -> mp (restf()) in mp cis
-- now we can define a Fibonacci stream as follows...
fibs : () -> CIS Int
fibs() = -- two recursive fix's, second already lazy...
let fibsgen = fixy (\ fn (CIS (f, s) restf) ->
CIS (s, f + s) (\ () -> fn () (restf())))
in fixy (\ cisthnk -> fibsgen (CIS (0, 1) cisthnk))
|> mapCIS (\ (v, _) -> v)
nCISs2String : Int -> CIS a -> String -- convert n CIS's to String
nCISs2String n cis =
let loop i (CIS head restf) rslt =
if i <= 0 then rslt ++ " )" else
loop (i - 1) (restf()) (rslt ++ " " ++ Debug.toString head)
in loop n cis "("
-- unfortunately, if we need CIS memoization so as
-- to make a true lazy list, Elm doesn't support it!!!
main : Html Never
main =
String.fromInt (facz 10) ++ " " ++ String.fromInt (fibz 10)
++ " " ++ String.fromInt (facy 10) ++ " " ++ String.fromInt (fiby 10)
++ " " ++ nCISs2String 20 (fibs())
|> text</syntaxhighlight>
{{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>
 
=={{header|Erlang}}==
<langsyntaxhighlight lang="erlang">Y = fun(M) -> (fun(X) -> X(X) end)(fun (F) -> M(fun(A) -> (F(F))(A) end) end) end.
 
Fac = fun (F) ->
Line 2,322 ⟶ 2,896:
end.
(Y(Fac))(5). %% 120
(Y(Fib))(8). %% 21</langsyntaxhighlight>
 
=={{header|F Sharp|F#}}==
===March 2024===
<lang fsharp>type 'a mu = Roll of ('a mu -> 'a) // ' fixes ease syntax colouring confusion with
In spite of everything that follows I am going to go with this.
<syntaxhighlight lang="fsharp">
// Y combinator. Nigel Galloway: March 5th., 2024
type Y<'T> = { eval: Y<'T> -> ('T -> 'T) }
let Y n g=let l = { eval = fun l -> fun x -> (n (l.eval l)) x } in (l.eval l) g
let fibonacci=function 0->1 |x->let fibonacci f= function 0->0 |1->1 |x->f(x - 1) + f(x - 2) in Y fibonacci x
let factorial n=let factorial f=function 0->1 |x->x*f(x-1) in Y factorial n
printfn "fibonacci 10=%d\nfactorial 5=%d" (fibonacci 10) (factorial 5)
</syntaxhighlight>
{{output}}
<pre>
fibonacci 10=55
factorial 5=120
</pre>
===Pre March 2024===
<syntaxhighlight lang="fsharp">type 'a mu = Roll of ('a mu -> 'a) // ' fixes ease syntax colouring confusion with
let unroll (Roll x) = x
Line 2,334 ⟶ 2,924:
let fix f = let g = fun x a -> f (unroll x x) a in g (Roll g)
// val fix : (('a -> 'b) -> 'a -> 'b) -> 'a -> 'b = <fun>
 
// Although true to the factorial definition, the
// recursive call is not in tail call position, so can't be optimized
Line 2,340 ⟶ 2,930:
//let fac = fix (fun f n -> if n < 2 then 1I else bigint n * f (n - 1))
// val fac : (int -> BigInteger) = <fun>
 
// much better progressive calculation in tail call position...
let fac = fix (fun f n i -> if i < 2 then n else f () (bigint i * n) (i - 1)) <| 1I
// val fac : (int -> BigInteger) = <fun>
 
// Although true to the definition of Fibonacci numbers,
// this can't be tail call optimized and recursively repeats calculations
Line 2,350 ⟶ 2,940:
// let fib = fix (fun fnc n -> if n < 2 then n else fnc (n - 1) + fnc (n - 2))
// val fib : (int -> BigInteger) = <fun>
 
// much better progressive calculation in tail call position...
let fib = fix (fun fnc f s i -> if i < 2 then f else fnc s (f + s) (i - 1)) 1I 1I
Line 2,359 ⟶ 2,949:
fac 10 |> printfn "%A" // prints 3628800
fib 10 |> printfn "%A" // prints 55
0 // return an integer exit code</langsyntaxhighlight>
{{output}}
<pre>3628800
Line 2,368 ⟶ 2,958:
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:
 
<langsyntaxhighlight lang="fsharp">// same as previous...
type 'a mu = Roll of ('a mu -> 'a) // ' fixes ease syntax colouring confusion with
Line 2,379 ⟶ 2,969:
// val fix : ((unit -> 'a) -> 'a -> 'a) = <fun>
 
// same efficient version of factorial functionb with added deferred execution...
let fac = fix (fun f n i -> if i < 2 then n else f () (bigint i * n) (i - 1)) <| 1I
// val fac : (int -> BigInteger) = <fun>
 
// same efficient version of factorialFibonacci function with added deferred execution...
let fib = fix (fun fnc f s i -> if i < 2 then f else fnc () s (f + s) (i - 1)) 1I 1I
// val fib : (int -> BigInteger) = <fun>
Line 2,390 ⟶ 2,980:
type CIS<'a> = CIS of 'a * (unit -> CIS<'a>) // ' fix formatting
 
// Using a double Y-Combinator recursion...
// define a continuous stream of Fibonacci numbers; there are other simpler ways,
// defines a continuous stream of Fibonacci numbers; there are other simpler ways,
// this way does not use recursion at all by using the Y-combinator, although it is
// this way implements recursion by using the Y-combinator, although it is
// much slower than other ways due to the many additional function calls and memory allocations,
// much slower than other ways due to the many additional function calls,
// it demonstrates something that can't be done with the Z-combinator...
let fibs() =
let fbsgen := fix (CIS<bigint>fun ->fnc (CIS<bigint>((f, s), =rest)) ->
fix (fun fnc f ( CIS((s, restf + s), fun() -> fnc () <| rest()))
Seq.unfold (fun (CIS(f(v, + s_), fun(rest)) -> fnc Some() s <|v, rest())) 1I
<| fix (fun cis -> fbsgen (CIS((1I, 0I), cis))) // cis is a lazy thunk!
Seq.unfold
(fun (CIS(hd, rest)) -> Some(hd, rest()))
<| fix (fun cis -> fbsgen (CIS(0I, cis)))
 
[<EntryPoint>]
Line 2,406 ⟶ 2,995:
fac 10 |> printfn "%A" // prints 3628800
fib 10 |> printfn "%A" // prints 55
fibs() |> Seq.take 20 |> Seq.iter (printf "%A ") // prints 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181 6765
printfn ""
0 // return an integer exit code</langsyntaxhighlight>
{{output}}
<pre>3628800
55
0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181 6765 </pre>
 
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:
<langsyntaxhighlight lang="fsharp">let rec fix f = f <| fun() -> fix f
// 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.</langsyntaxhighlight>
 
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,426 ⟶ 3,015:
=={{header|Factor}}==
In rosettacode/Y.factor
<langsyntaxhighlight lang="factor">USING: fry kernel math ;
IN: rosettacode.Y
: Y ( quot -- quot )
Line 2,435 ⟶ 3,024:
 
: almost-fib ( quot -- quot )
'[ dup 2 >= [ 1 2 [ - @ ] bi-curry@ bi + ] when ] ;</langsyntaxhighlight>
In rosettacode/Y-tests.factor
<langsyntaxhighlight lang="factor">USING: kernel tools.test rosettacode.Y ;
IN: rosettacode.Y.tests
 
[ 120 ] [ 5 [ almost-fac ] Y call ] unit-test
[ 8 ] [ 6 [ almost-fib ] Y call ] unit-test</langsyntaxhighlight>
running the tests :
<pre> ( scratchpad - auto ) "rosettacode.Y" test
Line 2,449 ⟶ 3,038:
 
=={{header|Falcon}}==
<syntaxhighlight lang="falcon">
<lang Falcon>
Y = { f => {x=> {n => f(x(x))(n)}} ({x=> {n => f(x(x))(n)}}) }
facStep = { f => {x => x < 1 ? 1 : x*f(x-1) }}
Line 2,459 ⟶ 3,048:
> "Factorial 10: ", YFac(10)
> "Fibonacci 10: ", YFib(10)
</syntaxhighlight>
</lang>
 
=={{header|Forth}}==
<syntaxhighlight lang="forth">
<lang Forth>\ Address of an xt.
\ Begin of approach. Depends on 'latestxt' word of GForth implementation.
 
: self-parameter ( xt -- xt' )
>r :noname latestxt postpone literal r> compile, postpone ;
;
: Y ( xt -- xt' )
dup self-parameter 2>r
:noname 2r> postpone literal compile, postpone ;
;
</syntaxhighlight>Usage:<syntaxhighlight lang="forth">
\ Fibonnacci test
10 :noname ( u xt -- u' ) over 2 < if drop exit then >r 1- dup r@ execute swap 1- r> execute + ; Y execute . 55 ok
\ Factorial test
10 :noname ( u xt -- u' ) over 2 < if 2drop 1 exit then over 1- swap execute * ; Y execute . 3628800 ok
 
\ End of approach.
</syntaxhighlight><syntaxhighlight lang="forth">\ Address of an xt.
variable 'xt
\ Make room for an xt.
Line 2,473 ⟶ 3,079:
: y, ( xt1 -- xt2 ) >r :noname @xt, r> compile, postpone ; ;
\ Make a new instance of the Y combinator.
: y ( xt1 -- xt2 ) xt, y, dup !xt ;</langsyntaxhighlight>
 
Samples:
<langsyntaxhighlight Forthlang="forth">\ Factorial
10 :noname ( u1 xt -- u2 ) over ?dup if 1- swap execute * else 2drop 1 then ;
y execute . 3628800 ok
Line 2,483 ⟶ 3,089:
10 :noname ( u1 xt -- u2 ) over 2 < if drop else >r 1- dup r@ execute swap 1- r> execute + then ;
y execute . 55 ok
</syntaxhighlight>
</lang>
 
=={{header|GAP}}==
<langsyntaxhighlight lang="gap">Y := function(f)
local u;
u := x -> x(x);
Line 2,520 ⟶ 3,126:
 
Y(fac)(8);
# 40320</langsyntaxhighlight>
 
=={{header|Genyris}}==
{{trans|Scheme}}
<langsyntaxhighlight lang="genyris">def fac (f)
function (n)
if (equal? n 0) 1
Line 2,542 ⟶ 3,148:
 
assertEqual ((Y fac) 5) 120
assertEqual ((Y fib) 8) 21</langsyntaxhighlight>
 
=={{header|Go}}==
<langsyntaxhighlight lang="go">package main
 
import "fmt"
Line 2,585 ⟶ 3,191:
return f(x-1)+f(x-2)
}
}</langsyntaxhighlight>
{{out}}
<pre>
Line 2,593 ⟶ 3,199:
 
The usual version using recursion, disallowed by the task:
<langsyntaxhighlight lang="go">func Y(f FuncFunc) Func {
return func(x int) int {
return f(Y(f))(x)
}
}</langsyntaxhighlight>
 
=={{header|Groovy}}==
Here is the simplest (unary) form of applicative order Y:
<langsyntaxhighlight lang="groovy">def Y = { le -> ({ f -> f(f) })({ f -> le { x -> f(f)(x) } }) }
 
def factorial = Y { fac ->
Line 2,613 ⟶ 3,219:
}
 
assert fib(10) == 55</langsyntaxhighlight>
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:
<langsyntaxhighlight 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 } }
Line 2,623 ⟶ 3,229:
1.upto(10) {
assert mul(it, 10) == it * 10
}</langsyntaxhighlight>
 
=={{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.
<langsyntaxhighlight lang="haskell">newtype Mu a = Roll
{ unroll :: Mu a -> a }
Line 2,672 ⟶ 3,278:
[ map fac [1 .. 20]
, take 20 $ fibs()
]</langsyntaxhighlight>
 
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:
 
<langsyntaxhighlight 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,
-- instead of the function that uses it...
Line 2,723 ⟶ 3,329:
, map fib [1 .. 20]
, take 20 fibs()
]</langsyntaxhighlight>
 
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 2,731 ⟶ 3,337:
=={{header|J}}==
 
See also: [[j:Essays/Combinators]]
===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.
<langsyntaxhighlight 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')
)
</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.
 
The factorial and Fibonacci examples follow:
<langsyntaxhighlight lang="j"> 'if. * y do. y * u <: y else. 1 end.' Y 10 NB. Factorial
3628800
'(u@:<:@:<: + u@:<:)^:(1 < ])' Y 10 NB. Fibonacci
55</langsyntaxhighlight>
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):
<langsyntaxhighlight 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
Line 2,753 ⟶ 3,360:
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</langsyntaxhighlight>
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),
<langsyntaxhighlight 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')</langsyntaxhighlight>
The following are examples of anonymous dyadic and ambivalent recursions,
<langsyntaxhighlight lang="j"> 1 2 3 '([:`(>:@:])`(<:@:[ u 1:)`(<:@[ u [ u <:@:])@.(#.@,&*))'XY"0/ 1 2 3 4 5 NB. Ackermann function...
3 4 5 6 7
5 7 9 11 13
Line 2,770 ⟶ 3,377:
8 11 20 41 86 179 368
NB. OEIS A097813 - main diagonal
NB. OEIS A050488 = A097813 - 1 - adyacent upper off-diagonal</langsyntaxhighlight>
 
J supports directly anonymous tacit recursion via the verb $: and for tacit recursions, XY is equivalent to the adverb,
<langsyntaxhighlight lang="j">YX=. (1 :'('':''<@;(1;~":0)<@;<@((":0)&;))u')($:`)(`:6)</langsyntaxhighlight>
 
===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):
<langsyntaxhighlight lang="j">Y=. ((((&>)/)((((^:_1)b.)(`(<'0';_1)))(`:6)))(&([ 128!:2 ,&<)))</langsyntaxhighlight>
The factorial and Fibonacci examples:
<langsyntaxhighlight lang="j"> u=. [ NB. Function (left)
n=. ] NB. Argument (right)
sr=. [ apply f. ,&< NB. Self referring
Line 2,789 ⟶ 3,396:
Fib=. ((u sr n - 2:) + u sr n - 1:) ^: (1 < n)
Fib f. Y 10
55</langsyntaxhighlight>
The stateless functions are shown next (the f. adverb replaces all embedded names by its referents):
<langsyntaxhighlight lang="j"> fac f. Y NB. Factorial...
'1:`(] * [ ([ 128!:2 ,&<) ] - 1:)@.(0 < ])&>/'&([ 128!:2 ,&<)
 
Line 2,802 ⟶ 3,409:
 
Fib f. NB. Fibonacci step...
(([ ([ 128!:2 ,&<) ] - 2:) + [ ([ 128!:2 ,&<) ] - 1:)^:(1 < ])</langsyntaxhighlight>
A structured derivation of Y follows:
<langsyntaxhighlight lang="j"> sr=. [ apply f.,&< NB. Self referring
lv=. (((^:_1)b.)(`(<'0';_1)))(`:6) NB. Linear representation of a verb argument
Y=. (&>)/lv(&sr) NB. Y with embedded states
Y=. 'Y'f. NB. Fixing it...
Y NB. ... To make it stateless (i.e., a combinator)
((((&>)/)((((^:_1)b.)(`_1))(`:6)))(&([ 128!:2 ,&<)))</langsyntaxhighlight>
 
===Explicit alternate implementation===
Line 2,815 ⟶ 3,422:
Another approach:
 
<langsyntaxhighlight lang="j">Y=:1 :0
f=. u Defer
(5!:1<'f') f y
Line 2,834 ⟶ 3,441:
if. 2 > y do. y
else. (x`:6 y-1) + x`:6 y-2 end.
)</langsyntaxhighlight>
 
Example use:
 
<langsyntaxhighlight Jlang="j"> almost_factorial Y 9
362880
almost_fibonacci Y 9
34
almost_fibonacci Y"0 i. 10
0 1 1 2 3 5 8 13 21 34</langsyntaxhighlight>
 
Or, if you would prefer to not have a dependency on the definition of Defer, an equivalent expression would be:
 
<langsyntaxhighlight Jlang="j">Y=:2 :0(0 :0)
NB. this block will be n in the second part
:
Line 2,855 ⟶ 3,462:
f=. u (1 :n)
(5!:1<'f') f y
)</langsyntaxhighlight>
 
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 2,861 ⟶ 3,468:
For example:
 
<langsyntaxhighlight Jlang="j"> almost_factorial f. Y 10
3628800</langsyntaxhighlight>
 
=={{header|Java}}==
 
{{works with|Java|8+}}
<langsyntaxhighlight lang="java5">import java.util.function.Function;
 
public interface YCombinator {
Line 2,891 ⟶ 3,498:
System.out.println("fac(10) = " + fac.apply(10));
}
}</langsyntaxhighlight>
{{out}}
<pre>
Line 2,898 ⟶ 3,505:
</pre>
The usual version using recursion, disallowed by the task:
<langsyntaxhighlight 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);
}</langsyntaxhighlight>
 
Another version which is disallowed because a function passes itself, which is also a kind of recursion:
<langsyntaxhighlight lang="java5"> public static <A,B> Function<A,B> Y(Function<Function<A,B>, Function<A,B>> f) {
return new Function<A,B>() {
public B apply(A x) {
Line 2,909 ⟶ 3,516:
}
};
}</langsyntaxhighlight>
 
{{works with|Java|pre-8}}
We define a generic function interface like Java 8's <code>Function</code>.
<langsyntaxhighlight lang="java5">interface Function<A, B> {
public B call(A x);
}
Line 2,965 ⟶ 3,572:
System.out.println("fac(10) = " + fac.call(10));
}
}</langsyntaxhighlight>
 
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).
 
<langsyntaxhighlight lang="java5">import java.util.function.Function;
 
@FunctionalInterface
Line 2,976 ⟶ 3,583:
return apply(this);
}
}</langsyntaxhighlight>
 
<langsyntaxhighlight lang="java5">import java.util.function.Function;
import java.util.function.UnaryOperator;
 
@FunctionalInterface
public interface FixedPoint<FUNCTION> extends Function<UnaryOperator<FUNCTION>, FUNCTION> {}</langsyntaxhighlight>
 
<langsyntaxhighlight lang="java5">import java.util.Arrays;
import java.util.Optional;
import java.util.function.Function;
Line 3,026 ⟶ 3,633:
return inputs -> apply((INPUTS[]) Arrays.stream(inputs).parallel().map(transformer).toArray());
}
}</langsyntaxhighlight>
 
<langsyntaxhighlight lang="java5">import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.Arrays;
Line 3,101 ⟶ 3,708:
).forEach(System.out::println);
}
}</langsyntaxhighlight>
 
{{out}} (may depend on which function gets processed first):
<syntaxhighlight lang="text">factorial[10] = 3628800
ackermann[3, 2] = 29
fibonacci[20] = 6765</langsyntaxhighlight>
 
=={{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:
<langsyntaxhighlight lang="javascript">function Y(f) {
var g = f((function(h) {
return function() {
Line 3,135 ⟶ 3,742:
return n > 1 ? f(n - 1) + f(n - 2) : n;
};
});</langsyntaxhighlight>
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
<langsyntaxhighlight lang="javascript">function Y(f) {
return (function(h) {
return h(h);
Line 3,145 ⟶ 3,752:
});
});
}</langsyntaxhighlight>
A functionally equivalent version using the implicit <code>this</code> parameter is also possible:
<langsyntaxhighlight lang="javascript">function pseudoY(f) {
return (function(h) {
return h(h);
Line 3,163 ⟶ 3,770:
var fib = pseudoY(function(n) {
return n > 1 ? this(n - 1) + this(n - 2) : n;
});</langsyntaxhighlight>
However, <code>pseudoY()</code> is not a fixed-point combinator.
 
The usual version using recursion, disallowed by the task:
<langsyntaxhighlight lang="javascript">function Y(f) {
return function() {
return f(Y(f)).apply(this, arguments);
};
}</langsyntaxhighlight>
 
Another version which is disallowed because it uses <code>arguments.callee</code> for a function to get itself recursively:
<langsyntaxhighlight lang="javascript">function Y(f) {
return function() {
return f(arguments.callee).apply(this, arguments);
};
}</langsyntaxhighlight>
===ECMAScript 2015 (ES6) variants===
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:
<langsyntaxhighlight lang="javascript">let
Y= // Except for the η-abstraction necessary for applicative order languages, this is the formal Y combinator.
f=>((g=>(f((...x)=>g(g)(...x))))
Line 3,201 ⟶ 3,808:
fact=>(n,m=1)=>n<2?m:fact(n-1,n*m);
tailfact= // Tail call version of factorial function
Y(opentailfact);</langsyntaxhighlight>
ECMAScript 2015 (ES6) also permits a really compact polyvariadic variant for mutually recursive functions:
<langsyntaxhighlight lang="javascript">let
polyfix= // A version that takes an array instead of multiple arguments would simply use l instead of (...l) for parameter
(...l)=>(
Line 3,211 ⟶ 3,818:
polyfix(
(even,odd)=>n=>(n===0)||odd(n-1),
(even,odd)=>n=>(n!==0)&&even(n-1));</langsyntaxhighlight>
 
A minimalist version:
 
<langsyntaxhighlight 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);</langsyntaxhighlight>
 
=={{header|Joy}}==
<langsyntaxhighlight 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.</lang>
 
=={{header|Julia}}==
<langsyntaxhighlight lang="julia">
_
julia> """
_ _ _(_)_ | Documentation: https://docs.julialang.org
# Y combinator
(_) | (_) (_) |
_ _ _| |_ __ _ | Type "?" for help, "]?" for Pkg help.
| | | | | | |/ _` | |
| | |_| | | | (_| | | Version 1.6.3 (2021-09-23)
_/ |\__'_|_|_|\__'_| | Official https://julialang.org/ release
|__/ |
 
julia> using Markdown
 
julia> @doc md"""
# Y Combinator
 
* `$λf. (λx. f (x x)) (λx. f (x x))`$
""" ->
Y = f -> (x -> x(x))(y -> f((t...) -> y(y)(t...)))
Y
</lang>
</syntaxhighlight>
 
Usage:
 
<langsyntaxhighlight lang="julia">
julia> fac = f -> (n -> n < 2 ? 1 : n * f(n - 1))
julia> "# Factorial"
#9 (generic function with 1 method)
fac = f -> (n -> n < 2 ? 1 : n * f(n - 1))
 
julia> fib = f -> (n -> n == 0 ? 0 : (n == 1 ? 1 : f(n - 1) + f(n - 2)))
julia> "# Fibonacci"
#13 (generic function with 1 method)
fib = f -> (n -> n == 0 ? 0 : (n == 1 ? 1 : f(n - 1) + f(n - 2)))
 
julia> [Y(fac).(i) for i = 1:10])
10-element ArrayVector{Any,1Int64}:
1
2
Line 3,255 ⟶ 3,873:
3628800
 
julia> [Y(fib).(i) for i = 1:10])
10-element ArrayVector{Any,1Int64}:
1
1
Line 3,267 ⟶ 3,885:
34
55
</syntaxhighlight>
</lang>
 
=={{header|Kitten}}==
 
<langsyntaxhighlight lang="kitten">define y<S..., T...> (S..., (S..., (S... -> T...) -> T...) -> T...):
-> f; { f y } f call
 
Line 3,289 ⟶ 3,907:
5 \fac y say // 120
10 \fib y say // 55
</syntaxhighlight>
</lang>
 
=={{header|Klingphix}}==
<syntaxhighlight lang="klingphix">:fac
dup 1 great [dup 1 sub fac mult] if
;
 
:fib
dup 1 great [dup 1 sub fib swap 2 sub fib add] if
;
 
:test
print ": " print
10 [over exec print " " print] for
nl
;
 
@fib "fib" test
@fac "fac" test
 
"End " input</syntaxhighlight>
{{out}}
<pre>fib: 1 1 2 3 5 8 13 21 34 55
fac: 1 2 6 24 120 720 5040 40320 362880 3628800
End</pre>
 
=={{header|Kotlin}}==
<langsyntaxhighlight lang="scala">// version 1.1.2
 
typealias Func<T, R> = (T) -> R
Line 3,313 ⟶ 3,958:
for (i in 1..10) print("${y(::fib)(i)} ")
println()
}</langsyntaxhighlight>
 
{{out}}
Line 3,322 ⟶ 3,967:
 
=={{header|Lambdatalk}}==
Tested in http://epsilonwikilambdaway.free.fr/lambdawaylambdawalks/?view=Ycombinator
 
<syntaxhighlight lang="scheme">
<lang Scheme>
1) defining the Ycombinator
{def Y {lambda {:f} {:f :f}}}
{lambda {:f :n}
{:f :f :n}}}
 
2) defining non recursive functions
Line 3,346 ⟶ 3,989:
 
3) testing
{{Y almost-fac} 6}
-> 720
{{Y almost-fibo} 8}
-> 34
 
</syntaxhighlight>
We could also forget the Ycombinator and names:
 
=={{header|Lang}}==
1) fac:
Y combinator function:
{{lambda {:f :n} {:f :f :n}}
<syntaxhighlight lang="lang">
{lambda {:f :n}
# Disable warning for shadowing of predefined function
{if {= :n 1}
lang.errorOutput = -1
then 1
else {* :n {:f :f {- :n 1}}}}} 6}
-> 720
 
fp.combY = (fp.f) -> {
2) fibo:
# fp.f must be provided by the function with a partially called combinator function, because fp.f will not be available in the callee scope
{{lambda {:f :n} {:f :f :n}}
fp.func = (fp.f, fp.x) -> {
{{lambda {:f :n}
fp.callFunc = (fp.f, fp.x, &args...) -> return fp.f(fp.x(fp.x))(&args...)
{if {< :n 2} then 1
else {+ {:f :f {- :n 1}} {:f :f {- :n 2}}}}}} 8}
return fn.combAN(fp.callFunc, fp.f, fp.x)
-> 34
}
return fn.combM(fn.combA2(fp.func, fp.f))
}
 
# Re-enable warning output
lang.errorOutput = 1
</syntaxhighlight>
 
Usage (Factorial):
<syntaxhighlight lang="lang">
fp.fac = (fp.func) -> {
fp.retFunc = (fp.func, $n) -> {
return parser.op($n < 2?1:$n * fp.func($n - 1))
}
return fn.combAN(fp.retFunc, fp.func)
}
 
# Apply Y combinator
fp.facY = fp.combY(fp.fac)
 
# Use function
fn.println(fp.facY(10))
</syntaxhighlight>
 
Usage (Fibonacci):
<syntaxhighlight lang="lang">
fp.fib = (fp.func) -> {
fp.retFunc = (fp.func, $x) -> {
return parser.op($x < 2?1:fp.func($x - 2) + fp.func($x - 1))
}
return fn.combAN(fp.retFunc, fp.func)
}
 
fp.fibY = fp.combY(fp.fib)
 
fn.println(fp.fibY(10))
</lang>
</syntaxhighlight>
 
=={{header|Lua}}==
<langsyntaxhighlight lang="lua">Y = function (f)
return function(...)
return (function(x) return x(x) end)(function(x) return f(function(y) return x(x)(y) end) end)(...)
end
end
</syntaxhighlight>
</lang>
 
Usage:
 
<langsyntaxhighlight 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
factorial, fibs = Y(almostfactorial), Y(almostfibs)
print(factorial(7))</langsyntaxhighlight>
 
=={{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.
<syntaxhighlight lang="m2000 interpreter">
<lang M2000 Interpreter>
Module Ycombinator {
\\ y() return value. no use of closure
y=lambda (g, x)->g(g, x)
Print y(lambda (g, n as decimal)->if(n=0->1, n*g(g, n-1)), 10)=3628800 ' true
Print y(lambda (g, n)->if(n<=1->n,g(g, n-1)+g(g, n-2)), 10)=55 ' true
\\ Using closure in y, y() return function
y=lambda (g)->lambda g (x) -> g(g, x)
fact=y((lambda (g, n as decimal)-> if(n=0->1, n*g(g, n-1))))
Print fact(6)=720, fact(24)=620448401733239439360000@
fib=y(lambda (g, n)->if(n<=1->n, g(g, n-1)+g(g, n-2)))
Print fib(10)=55
}
Ycombinator
</syntaxhighlight>
</lang>
 
<syntaxhighlight lang="m2000 interpreter">
<lang M2000 Interpreter>
Module Checkit {
Rem {
\\ all lambda arguments passed by value in this example
all lambda arguments passed by value in this example
\\ There is no recursion in these lambdas
There is no recursion in these lambdas
\\ Y combinator make argument f as closure, as a copy of f
Y combinator make argument f \\as m(mclosure, argument) pass as first argument a copy of mf
m(m, argument) pass as first argument a copy of m
\\ so never a function, here, call itself, only call a copy who get it as argument before the call.
so never a function, here, call itself, only call a copy who get it as argument before the call.
Y=lambda (f)-> {
}
=lambda f (x)->f(f,x)
Y=lambda (f)-> {
}
fac_step =lambda f (m, nx)-> {f(f,x)
}
if n<2 then {
fac_step=lambda (m, n)-> {
=1
if n<2 then =1 else =n*m(m, n-1)
} else {
}
=n*m(m, n-1)
fac=Y(fac_step)
}
fib_step=lambda (m, n)-> {
}
if n<=1 then =n else =m(m, n-1)+m(m, n-2)
fac=Y(fac_step)
}
fib_step=lambda (m, n)-> {
fib=Y(fib_step)
if n<=1 then {
For i=1 to 10 {
=n
Print fib(i), fac(i)
} else {
}
=m(m, n-1)+m(m, n-2)
}
}
fib=Y(fib_step)
For i=1 to 10
Print fib(i), fac(i)
Next i
}
Checkit
Module CheckRecursion {
fac=lambda (n) -> {
if n<2 then {=1 else =n*Lambda(n-1)
}
=1
fib=lambda (n) -> {
} else {
if n<=1 then =n else =lambda(n-1)+lambda(n-2)
=n*Lambda(n-1)
}
}
For i=1 to 10:Print fib(i), fac(i):Next
}
fib=lambda (n) -> {
if n<=1 then {
=n
} else {
=lambda(n-1)+lambda(n-2)
}
}
For i=1 to 10
Print fib(i), fac(i)
Next i
}
CheckRecursion
</syntaxhighlight>
</lang>
 
=={{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:
<syntaxhighlight lang="manool">
<lang MANOOL>
{ {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
Line 3,471 ⟶ 4,134:
}
}
</syntaxhighlight>
</lang>
Using less syntactic sugar:
<syntaxhighlight lang="manool">
<lang MANOOL>
{ {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
Line 3,485 ⟶ 4,148:
}
}
</syntaxhighlight>
</lang>
{{output}}
<pre>
Line 3,511 ⟶ 4,174:
 
=={{header|Maple}}==
<syntaxhighlight lang="maple">
<lang Maple>
> Y:=f->(x->x(x))(g->f((()->g(g)(args)))):
> Yfac:=Y(f->(x->`if`(x<2,1,x*f(x-1)))):
Line 3,519 ⟶ 4,182:
> seq( Yfib( i ), i = 1 .. 10 );
1, 1, 2, 3, 5, 8, 13, 21, 34, 55
</syntaxhighlight>
</lang>
 
=={{header|Mathematica}} / {{header|Wolfram Language}}==
<langsyntaxhighlight Mathematicalang="mathematica">Y = Function[f, #[#] &[Function[g, f[g[g][##] &]]]];
factorial = Y[Function[f, If[# < 1, 1, # f[# - 1]] &]];
fibonacci = Y[Function[f, If[# < 2, #, f[# - 1] + f[# - 2]] &]];</langsyntaxhighlight>
 
=={{header|Moonscript}}==
<langsyntaxhighlight Moonscriptlang="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</langsyntaxhighlight>
 
=={{header|Nim}}==
 
<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
# the extra `T` argument to the function to be recursed...
 
import sugar
 
proc fixz[T, TResult](f: ((T) -> TResult) -> ((T) -> TResult)): (T) -> TResult =
type RecursiveFunc = object # any entity that wraps the recursion!
recfnc: ((RecursiveFunc) -> ((T) -> TResult))
let g = (x: RecursiveFunc) => f ((a: T) => x.recfnc(x)(a))
g(RecursiveFunc(recfnc: g))
 
let facz = fixz((f: (int) -> int) =>
((n: int) => (if n <= 1: 1 else: n * f(n - 1))))
let fibz = fixz((f: (int) -> int) =>
((n: int) => (if n < 2: n else: f(n - 2) + f(n - 1))))
 
echo facz(10)
echo fibz(10)
 
# by adding some laziness, we can get a true Y-Combinator...
# note that there is no specified parmater(s) - truly fix point!...
 
#[
proc fixy[T](f: () -> T -> T): T =
type RecursiveFunc = object # any entity that wraps the recursion!
recfnc: ((RecursiveFunc) -> T)
let g = ((x: RecursiveFunc) => f(() => x.recfnc(x)))
g(RecursiveFunc(recfnc: g))
# ]#
 
# same thing using direct recursion as Nim has...
# 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,
# instead of the function that uses it...
proc fixy[T](f: () -> T -> T): T = f(() => (fixy(f)))
 
# these are dreadfully inefficient as they becursively build stack!...
let facy = fixy((f: () -> (int -> int)) =>
((n: int) => (if n <= 1: 1 else: n * f()(n - 1))))
 
let fiby = fixy((f: () -> (int -> int)) =>
((n: int) => (if n < 2: n else: f()(n - 2) + f()(n - 1))))
 
echo facy 10
echo fiby 10
 
# something that can be done with the Y-Combinator that con't be done with the Z...
# given the following Co-Inductive Stream (CIS) definition...
type CIS[T] = object
head: T
tail: () -> CIS[T]
 
# Using a double Y-Combinator recursion...
# defines a continuous stream of Fibonacci numbers; there are other simpler ways,
# this way implements recursion by using the Y-combinator, although it is
# much slower than other ways due to the many additional function calls,
# it demonstrates something that can't be done with the Z-combinator...
iterator fibsy: int {.closure.} = # two recursions...
let fbsfnc: (CIS[(int, int)] -> CIS[(int, int)]) = # first one...
fixy((fnc: () -> (CIS[(int,int)] -> CIS[(int,int)])) =>
((cis: CIS[(int,int)]) => (
let (f,s) = cis.head;
CIS[(int,int)](head: (s, f + s), tail: () => fnc()(cis.tail())))))
var fbsgen: CIS[(int, int)] = # second recursion
fixy((cis: () -> CIS[(int,int)]) => # cis is a lazy thunk used directly below!
fbsfnc(CIS[(int,int)](head: (1,0), tail: cis)))
while true: yield fbsgen.head[0]; fbsgen = fbsgen.tail()
 
let fibs = fibsy
for _ in 1 .. 20: stdout.write fibs(), " "
echo()</syntaxhighlight>
{{out}}
<pre>3628800
55
3628800
55
0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181</pre>
 
At least this last example version building a sequence of Fibonacci numbers doesn't build stack as it the use of CIS's means that it is a type of continuation passing/trampolining style.
 
Note that these would likely never be practically used in Nim as the language offers both direct variable binding recursion and recursion on proc's as well as other forms of recursion so it would never normally be necessary. Also note that these implementations not using recursive bindings on variables are "non-sharing" fix point combinators, whereas sharing is sometimes desired/required and thus recursion on variable bindings is required.
 
=={{header|Objective-C}}==
{{works with|Mac OS X|10.6+}}{{works with|iOS|4.0+}}
<langsyntaxhighlight lang="objc">#import <Foundation/Foundation.h>
 
typedef int (^Func)(int);
Line 3,572 ⟶ 4,320:
}
return 0;
}</langsyntaxhighlight>
 
The usual version using recursion, disallowed by the task:
<langsyntaxhighlight lang="objc">Func Y(FuncFunc f) {
return ^(int x) {
return f(Y(f))(x);
};
}</langsyntaxhighlight>
 
=={{header|OCaml}}==
The Y-combinator over functions may be written directly in OCaml provided rectypes are enabled:
<langsyntaxhighlight lang="ocaml">let fix f g = (fun x a -> f (x x) a) (fun x a -> f (x x) a) g</langsyntaxhighlight>
Polymorphic variants are the simplest workaround in the absence of rectypes:
<langsyntaxhighlight lang="ocaml">let fix f = (fun (`X x) -> f(x (`X x))) (`X(fun (`X x) y -> f(x (`X x)) y));;</langsyntaxhighlight>
Otherwise, an ordinary variant can be defined and used:
<langsyntaxhighlight lang="ocaml">type 'a mu = Roll of ('a mu -> 'a);;
 
let unroll (Roll x) = x;;
Line 3,613 ⟶ 4,361:
 
fix fib 8;;
(* - : int = 21 *)</langsyntaxhighlight>
 
The usual version using recursion, disallowed by the task:
<langsyntaxhighlight lang="ocaml">let rec fix f x = f (fix f) x;;</langsyntaxhighlight>
 
=={{header|Oforth}}==
Line 3,622 ⟶ 4,370:
 
With recursion into Y definition (so non stateless Y) :
<langsyntaxhighlight Oforthlang="oforth">: Y(f) #[ f Y f perform ] ;</langsyntaxhighlight>
 
Without recursion into Y definition (stateless Y).
<langsyntaxhighlight Oforthlang="oforth">: X(me, f) #[ me f me perform f perform ] ;
: Y(f) #X f X ;</langsyntaxhighlight>
 
Usage :
<langsyntaxhighlight Oforthlang="oforth">: almost-fact(n, f) n ifZero: [ 1 ] else: [ n n 1 - f perform * ] ;
#almost-fact Y => fact
 
Line 3,639 ⟶ 4,387:
n 0 == ifTrue: [ 1 m 1 - f perform return ]
n 1 - m f perform m 1 - f perform ;
#almost-Ackermann Y => Ackermann </langsyntaxhighlight>
 
=={{header|Order}}==
<langsyntaxhighlight lang="c">#include <order/interpreter.h>
 
#define ORDER_PP_DEF_8y \
Line 3,660 ⟶ 4,408:
 
ORDER_PP(8to_lit(8ap(8y(8fac), 10))) // 3628800
ORDER_PP(8ap(8y(8fib), 10)) // 55</langsyntaxhighlight>
 
=={{header|Oz}}==
<langsyntaxhighlight lang="oz">declare
Y = fun {$ F}
{fun {$ X} {X X} end
Line 3,685 ⟶ 4,433:
in
{Show {Fac 5}}
{Show {Fib 8}}</langsyntaxhighlight>
 
=={{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.
<langsyntaxhighlight lang="parigp">Y(f)=x->f(f,x);
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));
apply(fact, [1..10])
apply(fib, [1..10])</langsyntaxhighlight>
{{out}}
<pre>%1 = [1, 2, 6, 24, 120, 720, 5040, 40320, 362880, 3628800]
Line 3,699 ⟶ 4,447:
 
=={{header|Perl}}==
<langsyntaxhighlight lang="perl">sub Y { my $f = shift; # λf.
sub { my $x = shift; $x->($x) }->( # (λx.x x)
sub {my $y = shift; $f->(sub {$y->($y)(@_)})} # λy.f λz.y y z
Line 3,712 ⟶ 4,460:
for my $f ($fac, $fib) {
print join(' ', map Y($f)->($_), 0..9), "\n";
}</langsyntaxhighlight>
{{out}}
<pre>1 1 2 6 24 120 720 5040 40320 362880
Line 3,718 ⟶ 4,466:
 
The usual version using recursion, disallowed by the task:
<langsyntaxhighlight lang="perl">sub Y { my $f = shift;
sub {$f->(Y($f))->(@_)}
}</langsyntaxhighlight>
 
=={{header|Phix}}==
Line 3,733 ⟶ 4,481:
[[Partial_function_application#Phix|Partial_function_application]],
and/or [[Function_composition#Phix|Function_composition]]
<!--<syntaxhighlight lang="phix">(phixonline)-->
<lang Phix>function call_fn(integer f, n)
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
return call_func(f,{f,n})
<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>
end function
<span style="color: #008080;">return</span> <span style="color: #7060A8;">call_func</span><span style="color: #0000FF;">(</span><span style="color: #000000;">f</span><span style="color: #0000FF;">,{</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;">end</span> <span style="color: #008080;">function</span>
function Y(integer f)
return f
<span style="color: #008080;">function</span> <span style="color: #000000;">Y</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">f</span><span style="color: #0000FF;">)</span>
end function
<span style="color: #008080;">return</span> <span style="color: #000000;">f</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
function fac(integer self, integer n)
return iff(n>1?n*call_fn(self,n-1):1)
<span style="color: #008080;">function</span> <span style="color: #000000;">fac</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">self</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">integer</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">)</span>
end function
<span style="color: #008080;">return</span> <span style="color: #008080;">iff</span><span style="color: #0000FF;">(</span><span style="color: #000000;">n</span><span style="color: #0000FF;">></span><span style="color: #000000;">1</span><span style="color: #0000FF;">?</span><span style="color: #000000;">n</span><span style="color: #0000FF;">*</span><span style="color: #000000;">call_fn</span><span style="color: #0000FF;">(</span><span style="color: #000000;">self</span><span style="color: #0000FF;">,</span><span style="color: #000000;">n</span><span style="color: #0000FF;">-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">):</span><span style="color: #000000;">1</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
function fib(integer self, integer n)
return iff(n>1?call_fn(self,n-1)+call_fn(self,n-2):n)
<span style="color: #008080;">function</span> <span style="color: #000000;">fib</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">self</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">integer</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">)</span>
end function
<span style="color: #008080;">return</span> <span style="color: #008080;">iff</span><span style="color: #0000FF;">(</span><span style="color: #000000;">n</span><span style="color: #0000FF;">></span><span style="color: #000000;">1</span><span style="color: #0000FF;">?</span><span style="color: #000000;">call_fn</span><span style="color: #0000FF;">(</span><span style="color: #000000;">self</span><span style="color: #0000FF;">,</span><span style="color: #000000;">n</span><span style="color: #0000FF;">-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">)+</span><span style="color: #000000;">call_fn</span><span style="color: #0000FF;">(</span><span style="color: #000000;">self</span><span style="color: #0000FF;">,</span><span style="color: #000000;">n</span><span style="color: #0000FF;">-</span><span style="color: #000000;">2</span><span style="color: #0000FF;">):</span><span style="color: #000000;">n</span><span style="color: #0000FF;">)</span>
 
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
procedure test(string name, integer rid=routine_id(name))
integer f = Y(rid)
<span style="color: #008080;">procedure</span> <span style="color: #000000;">test</span><span style="color: #0000FF;">(</span><span style="color: #004080;">string</span> <span style="color: #000000;">name</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">integer</span> <span style="color: #000000;">rid</span><span style="color: #0000FF;">=</span><span style="color: #7060A8;">routine_id</span><span style="color: #0000FF;">(</span><span style="color: #000000;">name</span><span style="color: #0000FF;">))</span>
printf(1,"%s: ",{name})
<span style="color: #004080;">integer</span> <span style="color: #000000;">f</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">Y</span><span style="color: #0000FF;">(</span><span style="color: #000000;">rid</span><span style="color: #0000FF;">)</span>
for i=1 to 10 do
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"%s: "</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">name</span><span style="color: #0000FF;">})</span>
printf(1," %d",call_fn(f,i))
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">10</span> <span style="color: #008080;">do</span>
end for
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">" %d"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">call_fn</span><span style="color: #0000FF;">(</span><span style="color: #000000;">f</span><span style="color: #0000FF;">,</span><span style="color: #000000;">i</span><span style="color: #0000FF;">))</span>
printf(1,"\n");
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
end procedure
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"\n"</span><span style="color: #0000FF;">);</span>
test("fac")
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>
test("fib")</lang>
<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>
<!--</syntaxhighlight>-->
{{out}}
<pre>
Line 3,766 ⟶ 4,517:
 
=={{header|Phixmonti}}==
<langsyntaxhighlight Phixmontilang="phixmonti">0 var subr
 
def fac
Line 3,790 ⟶ 4,541:
 
getid fac "fac" test
getid fib "fib" test</langsyntaxhighlight>
 
=={{header|PHP}}==
{{works with|PHP|5.3+}}
<langsyntaxhighlight lang="php"><?php
function Y($f) {
$g = function($w) use($f) {
Line 3,815 ⟶ 4,566:
 
echo $factorial(10), "\n";
?></langsyntaxhighlight>
The usual version using recursion, disallowed by the task:
<langsyntaxhighlight lang="php">function Y($f) {
return function() use($f) {
return call_user_func_array($f(Y($f)), func_get_args());
};
}</langsyntaxhighlight>
 
{{works with|PHP|pre-5.3 and 5.3+}}
with <tt>create_function</tt> instead of real closures. A little far-fetched, but...
<langsyntaxhighlight lang="php"><?php
function Y($f) {
$g = create_function('$w', '$f = '.var_export($f,true).';
Line 3,850 ⟶ 4,601:
$factorial = Y('almost_fac');
echo $factorial(10), "\n";
?></langsyntaxhighlight>
 
A functionally equivalent version using the <code>$this</code> parameter in closures is also possible:
{{works with|PHP|5.4+}}
<langsyntaxhighlight lang="php"><?php
function pseudoY($f) {
$g = function($w) use ($f) {
Line 3,873 ⟶ 4,624:
});
echo $fibonacci(10), "\n";
?></langsyntaxhighlight>
However, <code>pseudoY()</code> is not a fixed-point combinator.
 
=={{header|PicoLisp}}==
{{trans|Common Lisp}}
<langsyntaxhighlight PicoLisplang="picolisp">(de Y (F)
(let X (curry (F) (Y) (F (curry (Y) @ (pass (Y Y)))))
(X X) ) )</langsyntaxhighlight>
===Factorial===
<langsyntaxhighlight PicoLisplang="picolisp"># Factorial
(de fact (F)
(curry (F) (N)
Line 3,890 ⟶ 4,641:
 
: ((Y fact) 6)
-> 720</langsyntaxhighlight>
 
===Fibonacci sequence===
<langsyntaxhighlight PicoLisplang="picolisp"># Fibonacci
(de fibo (F)
(curry (F) (N)
Line 3,901 ⟶ 4,652:
 
: ((Y fibo) 22)
-> 28657</langsyntaxhighlight>
 
===Ackermann function===
<langsyntaxhighlight PicoLisplang="picolisp"># Ackermann
(de ack (F)
(curry (F) (X Y)
Line 3,913 ⟶ 4,664:
 
: ((Y ack) 3 4)
-> 125</langsyntaxhighlight>
 
=={{header|Pop11}}==
<langsyntaxhighlight lang="pop11">define Y(f);
procedure (x); x(x) endprocedure(
procedure (y);
Line 3,937 ⟶ 4,688:
 
Y(fac)(5) =>
Y(fib)(5) =></langsyntaxhighlight>
{{out}}
<pre>
Line 3,947 ⟶ 4,698:
{{trans|Joy}}
{{libheader|initlib}}
<langsyntaxhighlight lang="postscript">y {
{dup cons} exch concat dup cons i
}.
Line 3,954 ⟶ 4,705:
{ {pop zero?} {pop succ} {{dup pred} dip i *} ifte }
y
}.</langsyntaxhighlight>
 
=={{header|PowerShell}}==
Line 3,965 ⟶ 4,716:
Z & := & \lambda f.(\lambda x.f\ (\lambda y.x\ x\ y))\ (\lambda x.f\ (\lambda y.x\ x\ y)) \\
\end{array}</math>
<langsyntaxhighlight PowerShelllang="powershell">$fac = {
param([ScriptBlock] $f)
invoke-expression @"
Line 4,015 ⟶ 4,766:
 
$Z.InvokeReturnAsIs($fac).InvokeReturnAsIs(5)
$Z.InvokeReturnAsIs($fib).InvokeReturnAsIs(5)</langsyntaxhighlight>
 
 
GetNewClosure() was added in Powershell 2, allowing for an implementation without metaprogramming. The following was tested with Powershell 4.
 
<langsyntaxhighlight PowerShelllang="powershell">$Y = {
param ($f)
 
Line 4,067 ⟶ 4,818:
 
$Y.invoke($fact).invoke(5)
$Y.invoke($fib).invoke(5)</langsyntaxhighlight>
 
=={{header|Prolog}}==
Line 4,074 ⟶ 4,825:
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.
<langsyntaxhighlight Prologlang="prolog">:- use_module(lambda).
 
% The Y combinator
Line 4,105 ⟶ 4,856:
),
 
y(Fact, 10, FF), format('Fact(~w) = ~w~n', [10, FF]).</langsyntaxhighlight>
{{out}}
<pre>
Line 4,114 ⟶ 4,865:
 
=={{header|Python}}==
<langsyntaxhighlight 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))
>>> [ Y(fac)(i) for i in range(10) ]
Line 4,120 ⟶ 4,871:
>>> 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) ]
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34]</langsyntaxhighlight>
 
The usual version using recursion, disallowed by the task:
<langsyntaxhighlight lang="python">Y = lambda f: lambda *args: f(Y(f))(*args)</langsyntaxhighlight>
 
<langsyntaxhighlight lang="python">Y = lambda b: ((lambda f: b(lambda *x: f(f)(*x)))((lambda f: b(lambda *x: f(f)(*x)))))</langsyntaxhighlight>
 
=={{header|Q}}==
<syntaxhighlight lang="q">> Y: {{x x} {({y {(x x) y} x} y) x} x}
> fac: {{$[y<2; 1; y*x y-1]} x}
> (Y fac) 6
720j
> fib: {{$[y<2; 1; (x y-1) + (x y-2)]} x}
> (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
</syntaxhighlight>
 
=={{header|Quackery}}==
 
From the Wikipedia article [[wp:Fixed-point combinator#Implementation_in_other_languages|Fixed-point combinator]]:
 
:The Y combinator is a particular implementation of a fixed-point combinator in lambda calculus. Its structure is determined by the limitations of lambda calculus. It is not necessary or helpful to use this structure in implementing the fixed-point combinator in other languages.
 
<code>recursive</code> is a stateless fixed-point combinator which takes a stateless nest (named or nameless) and returns a recursive version of the nest.
 
As per the task it is used here to compute factorial and Fibonacci numbers.
 
Without the restriction on self referencing, <code>recursive</code> could be defined as <code>[ ' [ this ] swap nested join ]</code>.
 
<syntaxhighlight lang="quackery"> [ ' stack nested nested
' share nested join
swap nested join
dup dup 0 peek put ] is recursive ( x --> x )
 
[ over 2 < iff
[ 2drop 1 ] done
dip [ dup 1 - ] do * ] is factorial ( n x --> n )
 
[ over 2 < iff drop done
swap 1 - tuck 1 -
over do dip do + ] is fibonacci ( n x --> n )
 
say "8 factorial = " 8 ' factorial recursive do echo cr
say "8 fibonacci = " 8 ' fibonacci recursive do echo cr</syntaxhighlight>
 
{{out}}
 
<pre>8 factorial = 40320
8 fibonacci = 21
</pre>
 
=={{header|R}}==
<syntaxhighlight lang="r">
<lang R>Y <- function(f) {
#' Y = λf.(λs.ss)(λx.f(xx))
(function(x) { (x)(x) })( function(y) { f( (function(a) {y(y)})(a) ) } )
#' Z = λf.(λs.ss)(λx.f(λz.(xx)z))
}</lang>
#'
 
fixp.Y <- \ (f) (\ (x) (x) (x)) (\ (y) (f) ((y) (y))) # y-combinator
<lang R>fac <- function(f) {
fixp.Z <- \ (f) (\ (x) (x) (x)) (\ (y) (f) (\ (...) (y) (y) (...))) # z-combinator
function(n) {
</syntaxhighlight>
if (n<2)
1
else
n*f(n-1)
}
}
 
Y-combinator test:
fib <- function(f) {
 
function(n) {
<syntaxhighlight lang="r">
if (n <= 1)
fac.y <- fixp.Y (\ (f) \ (n) if (n<2) 1 else n*f(n-1))
n
fac.y(9) # [1] 362880
else
 
f(n-1) + f(n-2)
fib.y <- fixp.Y (\ (f) \ (n) if (n <= 1) n else f(n-1) + f(n-2))
}
fib.y(9) # [1] 34
}</lang>
</syntaxhighlight>
 
Z-combinator test:
 
<syntaxhighlight lang="r">
fac.z <- fixp.Z (\ (f) \ (n) if (n<2) 1 else n*f(n-1))
fac.z(9) # [1] 362880
 
fib.z <- fixp.Z (\ (f) \ (n) if (n <= 1) n else f(n-1) + f(n-2))
fib.z(9) # [1] 34
</syntaxhighlight>
 
You can verify these codes by [https://shinylive.io/r/editor/#code=NobwRAdghgtgpmAXGAZgSwB5wCYAcD2aEALgHQBOYANGAMb4lwlJgDEA5AAQCanAvJ0DdwClIAKQQGdSEiQEpxGUilEYMs2QB0IHTgC1+QkeKkz5gxcsEAvMatlX1WnVq3oMuUrwA8AWk4aNTlEUWSCAoLUI0JV1MMDRAE9okKDE6KTY1k4En3oYACMiKGJ8cldMD31ff3iU0XCYqKjohqSguobSLvSeoK7SdVCsq1z8AqKSsognLgBXCTgXCBQoWlIEzmq3D1562tCGiFC0FCCILwAmUIBGTjgAGwXOCAAqZQgfa8dl1fXRAE4hpxgNcALqcADMADYLgAOWEABiW6Hy602fm2nji7QO8SOnBOZ02Ai+zzujzgnHen1CAGoqaIPldNMs0KiEgCgSDwRCACxLVy-KzoqkVUj6PY4mpnY6nRmXG7kp6valfFkrNZWTmcLLcyEw+FI6as1HCrZiiUNFKHWVErwk0IQJWU1V0hlM74o0hawE64FgyH8iBgAC+oKAA here]
<lang R>for(i in 1:9) print(Y(fac)(i))
for(i in 1:9) print(Y(fib)(i))</lang>
 
=={{header|Racket}}==
 
The lazy implementation
<langsyntaxhighlight lang="racket">#lang lazy
 
(define Y (λ (f) ((λ (x) (f (x x))) (λ (x) (f (x x))))))
Line 4,163 ⟶ 4,964:
(Y (λ (fact) (λ (n) (if (zero? n) 1 (* n (fact (- n 1))))))))
(define Fib
(Y (λ (fib) (λ (n) (if (<= n 1) n (+ (fib (- n 1)) (fib (- n 2))))))))</langsyntaxhighlight>
 
{{out}}
Line 4,174 ⟶ 4,975:
 
Strict realization:
<langsyntaxhighlight lang="racket">#lang racket
(define Y (λ (b) ((λ (f) (b (λ (x) ((f f) x))))
(λ (f) (b (λ (x) ((f f) x)))))))</langsyntaxhighlight>
 
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:
<langsyntaxhighlight lang="racket">#lang typed/racket
 
(: make-recursive : (All (S T) ((S -> T) -> (S -> T)) -> (S -> T)))
Line 4,197 ⟶ 4,998:
(* n (fact (- n 1))))))))
 
(fact 5)</langsyntaxhighlight>
 
=={{header|Raku}}==
(formerly Perl 6)
<syntaxhighlight lang="raku" perl6line>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 fib (&f) { sub ($n) { $n < 2 ?? $n !! f($n - 1) + f($n - 2) } }
say map Y($_), ^10 for &fac, &fib;</langsyntaxhighlight>
{{out}}
<pre>(1 1 2 6 24 120 720 5040 40320 362880)
Line 4,211 ⟶ 5,012:
Note that Raku doesn't actually need a Y combinator because you can name anonymous functions from the inside:
 
<syntaxhighlight lang="raku" perl6line>say .(10) given sub (Int $x) { $x < 2 ?? 1 !! $x * &?ROUTINE($x - 1); }</langsyntaxhighlight>
 
=={{header|REBOL}}==
<langsyntaxhighlight lang="rebol">Y: closure [g] [do func [f] [f :f] closure [f] [g func [x] [do f :f :x]]]</langsyntaxhighlight>
;usage example
<langsyntaxhighlight lang="rebol">fact*: closure [h] [func [n] [either n <= 1 [1] [n * h n - 1]]]
fact: Y :fact*</langsyntaxhighlight>
 
=={{header|REXX}}==
Programming note: &nbsp; '''length''', &nbsp; '''reverse''', &nbsp; and'''sign''', &nbsp; '''trunc''', &nbsp; '''b2x''', &nbsp; '''d2x''', &nbsp; and &nbsp; '''x2d''' &nbsp; are REXX BIFs &nbsp; ('''B'''uilt '''I'''n '''F'''unctions).
<langsyntaxhighlight lang="rexx">/*REXX program implements and displays a stateless Y combinator. */
numeric digits 1000 /*allow big numbers. */
say ' fib' Y(fib (50) ) /*Fibonacci series. */
say ' fib' Y(fib (12 11 10 9 8 7 6 5 4 3 2 1 0) ) /*Fibonacci series. */
say ' fact' Y(fact (60) ) /*single factorial.*/
say ' fact' Y(fact (0 1 2 3 4 5 6 7 8 9 10 11) ) /*single factorial.*/
say ' Dfact' Y(dfact (4 5 6 7 8 9 10 11 12 13) ) /*double factorial.*/
say ' Tfact' Y(tfact (4 5 6 7 8 9 10 11 12 13) ) /*triple factorial.*/
say ' Qfact' Y(qfact (4 5 6 7 8 40) ) /*quadruple factorial.*/
say ' length' Y(length (when for to where whenceforth) ) /*lengths of words. */
say 'reverse' Y(reverse (23123 67866188 10073007 45.54 MAS I MA) ) /*reverses strings. */
say ' trunc sign' Y(truncsign (-7.00058 120 3.141598) 6.4 78.999)) /*truncatessign of the numbers. */
exit say ' trunc' Y(trunc (-7.0005 12 3.14159 6.4 78.999) ) /*sticktruncates anumbers. fork in it, we're all done. */
say ' b2x' Y(b2x (1 10 11 100 1000 10000 11111 ) ) /*converts BIN──►HEX. */
/*────────────────────────────────────────────────────────────────────────────*/
say ' Y: parsed2x' arg Y _; $= (d2x (8 9 10 11 12 88 89 90 91 6789) ) /*theconverts DEC──►HEX. Y combinator.*/
say ' x2d' Y(x2d (8 9 10 11 12 88 89 90 91 6789) ) /*converts HEX──►DEC. */
do j=1 for words(_); interpret '$=$' Y"("word(_,j)')'; end; return $
exit 0 /*stick a fork in it, we're all done. */
fib: procedure; parse arg x; if x<2 then return x; s=0; a=0; b=1
/*──────────────────────────────────────────────────────────────────────────────────────*/
s=0; a=0; b=1; do j=2 to x; s=a+b; a=b; b=s; end; return s
dfactY: procedure; parse arg xY _; !$=1; do j=x1 for towords(_); 2interpret '$=$' by -2; !=!*Y"("word(_,j)')'; end; return !$
/*──────────────────────────────────────────────────────────────────────────────────────*/
tfact: procedure; parse arg x; !=1; do j=x to 2 by -3; !=!*j; end; return !
qfactfib: procedure; parse arg x; !=1; doif j=x<2 tothen 2return x; by -4s= 0; ! a=!*j; end0; b= return !1
fact: procedure; parse arg x; !=1; do j=2 to x; s= a+b; a= b; ! b=!*j s; end; return !</lang>s
/*──────────────────────────────────────────────────────────────────────────────────────*/
'''output'''
dfact: procedure; parse arg x; != 1; do j=x to 2 by -2; != !*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 !
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:}}
<pre>
fib 12586269025
Line 4,253 ⟶ 5,059:
Qfact 4 5 12 21 32 3805072588800
length 4 3 2 5 11
reverse 32321 87688166 70017003 45.54 SAM I AM
sign -1 0 1
trunc -7 12 3 6 78
b2x 1 2 3 4 8 10 1F
d2x 8 9 A B C 58 59 5A 5B 1A85
x2d 8 9 16 17 18 136 137 144 145 26505
</pre>
 
Line 4,260 ⟶ 5,070:
Using a lambda:
 
<langsyntaxhighlight lang="ruby">y = lambda do |f|
lambda {|g| g[g]}[lambda do |g|
f[lambda {|*args| g[g][*args]}]
Line 4,270 ⟶ 5,080:
 
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]</langsyntaxhighlight>
 
Same as the above, using the new short lambda syntax:
{{works with|Ruby|1.9}}
<langsyntaxhighlight lang="ruby">y = ->(f) {->(g) {g.(g)}.(->(g) { f.(->(*args) {g.(g).(*args)})})}
fac = ->(f) { ->(n) { n < 2 ? 1 : n * f.(n-1) } }
Line 4,282 ⟶ 5,092:
fib = ->(f) { ->(n) { n < 2 ? n : f.(n-2) + f.(n-1) } }
 
p 10.times.map {|i| y.(fib).(i)}</langsyntaxhighlight>
 
Using a method:
 
{{works with|Ruby|1.9}}
<langsyntaxhighlight lang="ruby">def y(&f)
lambda do |g|
f.call {|*args| g[g][*args]}
Line 4,299 ⟶ 5,109:
# => [1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880]
p Array.new(10) {|i| fib[i]}
# => [0, 1, 1, 2, 3, 5, 8, 13, 21, 34]</langsyntaxhighlight>
 
The usual version using recursion, disallowed by the task:
<langsyntaxhighlight lang="ruby">y = lambda do |f|
lambda {|*args| f[y[f]][*args]}
end</langsyntaxhighlight>
 
=={{header|Rust}}==
 
{{works with|Rust|1.3544.01 stable}}
<syntaxhighlight lang="rust">
<lang rust>//! A simple implementation of the Y Combinator
//! A simple implementation of the Y Combinator:
// λf.(λx.xx)(λx.f(xx))
// <=>! λf.(λx.f(xx))(λx.f(xx))
//! <=> λf.(λx.f(xx))(λx.f(xx))
// CREDITS: A better version of the previous code that was posted here, with detailed explanation.
// See <y> and also <y_apply>.
// A function type that takes its own type as an input is an infinite recursive type.
// We introduce a trait that will allow us to have an input with the same type as self, and break the recursion.
// The input is going to be a trait object that implements the desired function in the interface.
// NOTE: We will be coercing a reference to a closure into this trait object.
 
/// A function type that takes its own type as an input is an infinite recursive type.
/// We introduce the "Apply" trait, which will allow us to have an input with the same type as self, and break the recursion.
/// The input is going to be a trait object that implements the desired function in the interface.
trait Apply<T, R> {
fn apply(&self, f: &dyn Apply<T, R>, t: T) -> R;
&self,
f: &dyn Apply<T, R>,
t: T
) -> R;
}
 
/// If we were to pass in self as f, we get:
// In Rust, closures fall into three kinds: FnOnce, FnMut and Fn.
/// λf.λt.sft
// FnOnce assumed to be able to be called just once if it is not Clone. It is impossible to
/// => λs.λt.sst [s/f]
// write recursive FnOnce that is not Clone.
/// => λs.ss
// All FnMut are also FnOnce, although you can call them multiple times, they are not allow to
impl<T, R, F> Apply<T, R> for F where F: Fn(&dyn Apply<T, R>, T) -> R {
// have a reference to themselves. So it is also not possible to write recursive FnMut closures
fn apply(&self, f: &dyn Apply<T, R>, t: T) -> R {
// that is not Clone.
self(f, t)
// All Fn are also FnMut, and all closures of Fn are also Clone. However, programmers can create
}
// Fn objects that are not Clone
 
// This will work for all Fn objects, not just closures
// And it is a little bit more efficient for Fn closures as it do not clone itself.
impl<T, R, F> Apply<T, R> for F where F:
Fn(&dyn Apply<T, R>, T) -> R
{
fn apply(
&self,
f: &dyn Apply<T, R>,
t: T
) -> R {
self(f, t)
// NOTE: Each letter is an individual symbol.
// (λx.(λy.xxy))(λx.(λy.f(λz.xxz)y))t
// => (λx.xx)(λx.f(xx))t
// => (Yf)t
}
}
 
/// (λt(λx.(λy.xxy))(λx.(λy.f(λz.xxz)y)))t
// This works for all closures that is Clone, and those are Fn.
/// => (λx.xx)(λx.f(xx))
// impl<T, R, F> Apply<T, R> for F where F: FnOnce( &Apply<T, R>, T ) -> R + Clone {
/// => Yf
// fn apply( &self, f: &Apply<T, R>, t: T ) -> R {
fn y<T, R>(f: impl Fn(&dyn Fn(T) -> R, T) -> R) -> impl Fn(T) -> R {
// (self.clone())( f, t )
move |t| (&|x: &dyn Apply<T, R>, y| x.apply(x, y))
// // If we were to(&|x: pass&dyn inApply<T, selfR>, asy| f(&|z| x.apply(x, wez), gety), -t)
// // NOTE: Each letter is an individual symbol.
// // λf.λt.sft
// // => λs.λt.sst [s/f]
// // => λs.ss
// }
// }
 
// Before 1.26 we have some limitations and so we need some workarounds. But now impl Trait is stable and we can
// write the following:
 
fn y<T,R>(f:impl Fn(&dyn Fn(T) -> R, T) -> R) -> impl Fn(T) -> R {
move |t| (
|x: &dyn Apply<T,R>, y| x.apply(x, y)
) (
&|x: &dyn Apply<T,R>, y| f(
&|z| x.apply(x,z),
y
),
t
)
}
 
/// Factorial of n.
// fn y<T,R>(f:impl FnOnce(&Fn(T) -> R, T) -> R + Clone) -> impl FnOnce(T) -> R {
// |t| (|x: &Apply<T,R>,y| x.apply(x,y))
// (&move |x:&Apply<T,R>,y| f(&|z| x.apply(x,z), y), t)
// // NOTE: Each letter is an individual symbol.
// // (λx.(λy.xxy))(λx.(λy.f(λz.xxz)y))t
// // => (λx.xx)(λx.f(xx))t
// // => (Yf)t
// }
 
// Previous version removed as they are just hacks when impl Trait is not available.
 
fn fac(n: usize) -> usize {
let almost_fac = |f: &dyn Fn(usize) -> usize, x| if x == 0 { 1 } else { x * f(x - 1) };
y(almost_fac)(n)
if x == 0 {
1
} else {
x * f(x - 1)
}
;
let fac = y( almost_fac );
fac(n)
}
 
/// nth Fibonacci number.
fn fib( n: usize ) -> usize {
fn let almost_fib = |ffib(n: &dyn Fn(usize) -> usize, x|{
let almost_fib = |f: &dyn Fn((usize, usize, usize)) -> usize, (a0, a1, x)|
if x < 2 {
1 match x {
} else { 0 => a0,
f(x - 2) + f(x - 1) => a1,
_ => f((a1, a0 + a1, x - 1)),
};
let fib = y(almost_fib) };
 
fib(n)
y(almost_fib)((1, 1, n))
}
 
/// Driver function.
fn optimal_fib( n: usize ) -> usize {
fn main() {
let almost_fib = |f: &dyn Fn((usize,usize,usize)) -> usize, (i0,i1,x)|
matchlet xn {= 10;
println!("fac({}) = {}", n, fac(n));
0 => i0,
println!("fib({}) = {}", n, fib(n));
1 => i1,
x => f((i1,i0+i1, x-1))
}
;
let fib = |x| y(almost_fib)((1,1,x));
fib(n)
}
 
</syntaxhighlight>
fn main() {
println!("{}", fac(10));
println!("{}", fib(10));
println!("{}", optimal_fib(10));
}</lang>
{{output}}
<pre>3628800
fac(10) = 3628800
89
fib(10) = 89
89</pre>
</pre>
 
=={{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]
<syntaxhighlight lang="scala">
<lang scala>def Y[A,B](f: (A=>B)=>(A=>B)) = {
def Y[A, case class WB](wff: W(A => B) => (A => B)): A => B = {
case class def applyW(wwf: W) => wf(wA => B)) {
def apply(w: W): A => B = wf(w)
}
val g: W => (A => B) = w => f(w(w))(_)
g(W(g))
}
}</lang>
</syntaxhighlight>
Example
<syntaxhighlight lang="scala">
<lang scala>val fac = 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
 
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</lang>
</syntaxhighlight>
 
=={{header|Scheme}}==
<langsyntaxhighlight lang="scheme">(define Y ; (Y f) = (g g) where
(lambda (f) ; (g g) = (f (lambda a (apply (g g) a)))
((lambda (g) (g g)) ; (Y f) == (f (lambda a (apply (Y f) a)))
Line 4,505 ⟶ 5,248:
 
(display (fib2 134))
(newline)</langsyntaxhighlight>
{{out}}
<pre>720
Line 4,512 ⟶ 5,255:
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
 
<langsyntaxhighlight lang="scheme">(define Yr ; (Y f) == (f (lambda a (apply (Y f) a)))
(lambda (f)
(f (lambda a (apply (Yr f) a)))))</langsyntaxhighlight>
 
And another way is:
<langsyntaxhighlight lang="scheme">(define Y2r
(lambda (f)
(lambda a (apply (f (Y2r f)) a))))</langsyntaxhighlight>
 
Which, non-recursively, is
<langsyntaxhighlight lang="scheme">(define Y2 ; (Y2 f) = (g g) where
(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)
(lambda a (apply (f (g g)) a))))))</langsyntaxhighlight>
 
=={{header|Shen}}==
<langsyntaxhighlight lang="shen">(define y
F -> ((/. X (X X))
(/. X (F (/. Z ((X X) Z))))))
Line 4,539 ⟶ 5,282:
(Fac 0)
(Fac 5)
(Fac 10)))</langsyntaxhighlight>
{{out}}
<pre>1
Line 4,546 ⟶ 5,289:
 
=={{header|Sidef}}==
<langsyntaxhighlight 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)) } }
Line 4,552 ⟶ 5,295:
 
var fib = ->(f) { ->(n) { n < 2 ? n : (f(n-2) + f(n-1)) } }
say 10.of { |i| y(fib)(i) }</langsyntaxhighlight>
{{out}}
<pre>
Line 4,561 ⟶ 5,304:
=={{header|Slate}}==
The Y combinator is already defined in slate as:
<langsyntaxhighlight lang="slate">Method traits define: #Y &builder:
[[| :f | [| :x | f applyWith: (x applyWith: x)]
applyWith: [| :x | f applyWith: (x applyWith: x)]]].</langsyntaxhighlight>
 
=={{header|Smalltalk}}==
{{works with|GNU Smalltalk}}
<langsyntaxhighlight 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)] ] ].
Line 4,575 ⟶ 5,318:
fact := Y value: [:f| [:i| i = 0 ifTrue: [1] ifFalse: [(f value: i-1) * i] ] ].
 
(fact value: 10) displayNl.</langsyntaxhighlight>
{{out}}
<pre>55
Line 4,581 ⟶ 5,324:
 
The usual version using recursion, disallowed by the task:
<langsyntaxhighlight lang="smalltalk">Y := [:f| [:x| (f value: (Y value: f)) value: x] ].</langsyntaxhighlight>
 
=={{header|Standard ML}}==
<langsyntaxhighlight lang="sml">- datatype 'a mu = Roll of ('a mu -> 'a)
fun unroll (Roll x) = x
 
Line 4,604 ⟶ 5,347:
val it = [1,1,2,6,24,120,720,5040,40320,362880] : int list
- List.tabulate (10, fix fib);
val it = [0,1,1,2,3,5,8,13,21,34] : int list</langsyntaxhighlight>
 
The usual version using recursion, disallowed by the task:
<langsyntaxhighlight lang="sml">fun fix f x = f (fix f) x</langsyntaxhighlight>
 
=={{header|SuperCollider}}==
 
Like Ruby, SuperCollider needs an extra level of lambda-abstraction to implement the y-combinator. The z-combinator is straightforward:
The direct implementation will not work, because SuperCollider evaluates x.(x) before calling f.
<lang SuperCollider>// z-combinator
<syntaxhighlight lang="supercollider">
y = { |f| { |x| f.(x.(x)) }.({ |x| f.(x.(x)) }) };
</syntaxhighlight>
 
For lazy evaluation, this call needs to be postponed by passing a function to f that makes this call (this is what is called the z-combinator):
<syntaxhighlight lang="supercollider">// z-combinator
 
z = { |f| { |x| f.({ |args| x.(x).(args) }) }.({ |x| f.({ |args| x.(x).(args) }) }) };
 
// this can be also factored differently
(
zy = { |f|
{ |xr| xr.(xr) }.(
{ |x| f.({ |args| x.(x).(args) }) }
{ |y|
f.({ |args| y.(y).(args) })
}
)
};
)
 
// the same in a shorterreduced form
 
(
Line 4,652 ⟶ 5,403:
 
 
</syntaxhighlight>
</lang>
 
=={{header|Swift}}==
Using a recursive type:
<langsyntaxhighlight lang="swift">struct RecursiveFunc<F> {
let o : RecursiveFunc<F> -> F
}
Line 4,672 ⟶ 5,423:
}
println("fac(5) = \(fac(5))")
println("fib(9) = \(fib(9))")</langsyntaxhighlight>
{{out}}
<pre>
Line 4,681 ⟶ 5,432:
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>)
<langsyntaxhighlight lang="swift">func Y<A, B>(f: (A -> B) -> A -> B) -> A -> B {
typealias RecursiveFunc = Any -> A -> B
let r : RecursiveFunc = { (z: Any) in let w = z as! RecursiveFunc; return f { w(w)($0) } }
return r(r)
}</langsyntaxhighlight>
 
The usual version using recursion, disallowed by the task:
<langsyntaxhighlight lang="swift">func Y<In, Out>( f: (In->Out) -> (In->Out) ) -> (In->Out) {
return { x in f(Y(f))(x) }
}</langsyntaxhighlight>
 
=={{header|Tailspin}}==
<langsyntaxhighlight lang="tailspin">
// YCombinator is not needed since tailspin supports recursion readily, but this demonstrates passing functions as parameters
templates combinator@&{stepper:}
templates makeStep@&{rec:}
$ -> stepper@&{next: rec@&{rec: rec}} !
end makeStep
$ -> makeStep@&{rec: makeStep} !
end combinator
templates factorial
templates seed@&{next:}
<=0> 1 !
<>
$ * ($ - 1 -> next) !
end seed
$ -> combinator@&{stepper: seed} !
end factorial
Line 4,716 ⟶ 5,467:
templates fibonacci
templates seed@&{next:}
<..1> $ !
<>
($ - 2 -> next) + ($ - 1 -> next) !
end seed
$ -> combinator@&{stepper: seed} !
end fibonacci
5 -> fibonacci -> 'fibonacci 5: $;
' -> !OUT::write
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 4,739 ⟶ 5,490:
This prints out 24, the factorial of 4:
 
<langsyntaxhighlight lang="txrlisp">;; The Y combinator:
(defun y (f)
[(op @1 @1)
Line 4,751 ⟶ 5,502:
 
;; Test:
(format t "~s\n" [[y fac] 4])</langsyntaxhighlight>
 
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 <langsyntaxhighlight lang="txrlisp">(op foo @1 (op bar @2 @@2))</langsyntaxhighlight>. 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}}==
The standard y combinator doesn't work in Ursala due to eager
evaluation, but an alternative is easily defined as shown
<langsyntaxhighlight Ursalalang="ursala">(r "f") "x" = "f"("f","x")
my_fix "h" = r ("f","x"). ("h" r "f") "x"</langsyntaxhighlight>
or by this shorter expression for the same thing in point free form.
<langsyntaxhighlight Ursalalang="ursala">my_fix = //~&R+ ^|H\~&+ ; //~&R</langsyntaxhighlight>
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
Line 4,771 ⟶ 5,522:
quotes signify a dummy variable. Using this
method, the definition of the factorial function becomes
<langsyntaxhighlight Ursalalang="ursala">#import nat
 
fact = my_fix "f". ~&?\1! product^/~& "f"+ predecessor</langsyntaxhighlight>
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
this,
<syntaxhighlight lang Ursala="ursala">#fix my_fix</langsyntaxhighlight>
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,
as in this example of a Fibonacci function.
<langsyntaxhighlight Ursalalang="ursala">fib = {0,1}?</1! sum+ fib~~+ predecessor^~/~& predecessor</langsyntaxhighlight>
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>
Line 4,790 ⟶ 5,541:
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.
<langsyntaxhighlight Ursalalang="ursala">#cast %nLW
 
examples = (fact* <1,2,3,4,5,6,7,8>,fib* <1,2,3,4,5,6,7,8>)</langsyntaxhighlight>
{{out}}
<pre>
Line 4,807 ⟶ 5,558:
(with 0 signifying the lowest order of fixed point combinators),
or if that's too easy, then by this definition.
<langsyntaxhighlight Ursalalang="ursala">#import sol
 
#fix general_function_fixer 1
 
my_fix "h" = "h" my_fix "h"</langsyntaxhighlight>
Note that this equation is solved using the next fixed point combinator in the hierarchy.
 
=={{header|VBA}}==
{{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.
<lang vb>Private Function call_fn(f As String, n As Long) As Long
call_fn = Application.Run(f, f, n)
End Function
Private Function Y(f As String) As String
Y = f
End Function
Private Function fac(self As String, n As Long) As Long
If n > 1 Then
fac = n * call_fn(self, n - 1)
Else
fac = 1
End If
End Function
Private Function fib(self As String, n As Long) As Long
If n > 1 Then
fib = call_fn(self, n - 1) + call_fn(self, n - 2)
Else
fib = n
End If
End Function
Private Sub test(name As String)
Dim f As String: f = Y(name)
Dim i As Long
Debug.Print name
For i = 1 To 10
Debug.Print call_fn(f, i);
Next i
Debug.Print
End Sub
 
Public Sub main()
test "fac"
test "fib"
End Sub</lang>{{out}}
<pre>fac
1 2 6 24 120 720 5040 40320 362880 3628800
fib
1 1 2 3 5 8 13 21 34 55 </pre>
 
=={{header|Verbexx}}==
<langsyntaxhighlight lang="verbexx">/////// Y-combinator function (for single-argument lambdas) ///////
 
y @FN [f]
Line 4,895 ⟶ 5,600:
 
@LOOP init:{ i = -1} while:(i <= 16) next:{i++}
{ @SAY "fibonacci<" i "> =" (@fibonacci i) };</langsyntaxhighlight>
 
=={{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.
<langsyntaxhighlight lang="vim">" Translated from Python. Works with: Vim 7.0
 
func! Lambx(sig, expr, dict)
Line 4,921 ⟶ 5,626:
echo Callx(Callx(g:Y, [g:fac]), [5])
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):
<langsyntaxhighlight lang="vim">
if !has("lambda")
echoerr 'Lambda feature required'
Line 4,933 ⟶ 5,638:
echo Y(Fac)(5)
echo map(range(10), 'Y(Fac)(v:val)')
</syntaxhighlight>
</lang>
Output:
<pre>120
Line 4,939 ⟶ 5,644:
 
=={{header|Wart}}==
<langsyntaxhighlight lang="python"># Better names due to Jim Weirich: http://vimeo.com/45140590
def (Y improver)
((fn(gen) gen.gen)
Line 4,952 ⟶ 5,657:
(n * (f n-1))))))
 
prn factorial.5</langsyntaxhighlight>
 
{{omit from|ACL2}}
Line 4,958 ⟶ 5,663:
{{omit from|PureBasic}}
{{omit from|TI-89 BASIC}} <!-- no lambdas, no first-class functions except by name string -->
 
=={{header|Wren}}==
{{trans|Go}}
<syntaxhighlight lang="wren">var y = Fn.new { |f|
var g = Fn.new { |r| f.call { |x| r.call(r).call(x) } }
return g.call(g)
}
 
var almostFac = Fn.new { |f| Fn.new { |x| x <= 1 ? 1 : x * f.call(x-1) } }
 
var almostFib = Fn.new { |f| Fn.new { |x| x <= 2 ? 1 : f.call(x-1) + f.call(x-2) } }
 
var fac = y.call(almostFac)
var fib = y.call(almostFib)
 
System.print("fac(10) = %(fac.call(10))")
System.print("fib(10) = %(fib.call(10))")</syntaxhighlight>
 
{{out}}
<pre>
fac(10) = 3628800
fib(10) = 55
</pre>
 
=={{header|XQuery}}==
Line 4,963 ⟶ 5,691:
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.
 
<langsyntaxhighlight XQuerylang="xquery">let $Y := function($f) {
(function($x) { ($x)($x) })( function($g) { $f( (function($a) { $g($g) ($a)}) ) } )
}
Line 4,972 ⟶ 5,700:
$fib(6)
)
</syntaxhighlight>
</lang>
{{out}}
<syntaxhighlight lang XQuery="xquery">720 8</langsyntaxhighlight>
 
=={{header|Yabasic}}==
<lang Yabasic>sub fac(self$, n)
if n > 1 then
return n * execute(self$, self$, n - 1)
else
return 1
end if
end sub
sub fib(self$, n)
if n > 1 then
return execute(self$, self$, n - 1) + execute(self$, self$, n - 2)
else
return n
end if
end sub
sub test(name$)
local i
print name$, ": ";
for i = 1 to 10
print execute(name$, name$, i);
next
print
end sub
 
test("fac")
test("fib")</lang>
 
=={{header|zkl}}==
<langsyntaxhighlight lang="zkl">fcn Y(f){ fcn(g){ g(g) }( 'wrap(h){ f( 'wrap(a){ h(h)(a) }) }) }</langsyntaxhighlight>
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.
<langsyntaxhighlight 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();
[0..10].apply(Y(almost_factorial)).println();</langsyntaxhighlight>
{{out}}
<pre>
Line 5,017 ⟶ 5,715:
L(1,1,2,6,24,120,720,5040,40320,362880,3628800)
</pre>
<langsyntaxhighlight 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();
[0..10].apply(Y(almost_fib)).println();</langsyntaxhighlight>
{{out}}
<pre>
2,172

edits