Man or boy test: Difference between revisions

→‎F#: Add CPS version of straightforward approach.
imported>GLChapman
(→‎F#: Add CPS version of straightforward approach.)
 
(33 intermediate revisions by 18 users not shown)
Line 227:
*   [[Jensen's Device]]
<br>
 
 
=={{header|Ada}}==
Line 234 ⟶ 233:
{{works with|Ada|Ada|2005, 2012}}
 
<langsyntaxhighlight lang="ada">with Ada.Text_IO; use Ada.Text_IO;
 
procedure Man_Or_Boy is
Line 269 ⟶ 268:
Zero'Access -- Returns 0
) ) );
end Man_Or_Boy;</langsyntaxhighlight>
 
Ada 2012 supports expression functions and conditional expressions which are used in the implementation below:
Line 275 ⟶ 274:
{{works with|Ada|Ada|2012}}
 
<langsyntaxhighlight lang="ada">with Ada.Text_IO; use Ada.Text_IO;
 
procedure Man_Or_Boy is
Line 304 ⟶ 303:
X4 => One'Access,
X5 => Zero'Access)));
end Man_Or_Boy;</langsyntaxhighlight>
 
This version resembles more Knuth's original version in that the result of B is thrown away.
 
<langsyntaxhighlight lang="ada">with Ada.Text_IO;
use Ada.Text_IO;
 
Line 348 ⟶ 347:
X5 => Zero'Access)));
 
end Man_Or_Boy;</langsyntaxhighlight>
 
Sample output:
Line 356 ⟶ 355:
 
=={{header|Aime}}==
<langsyntaxhighlight lang="aime">integer
F(list l)
{
Line 407 ⟶ 406:
 
0;
}</langsyntaxhighlight>
Output:
<pre>
Line 413 ⟶ 412:
</pre>
 
=={{header|ALGOL 60}} - Knuth's example==
Knuth's example:
'''begin'''
'''real''' '''procedure''' A (k, x1, x2, x3, x4, x5);
Line 452:
{{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] - due to extensive use of FORMATted transput}}
[[wp:Charles_H._Lindsey|Charles H. Lindsey]] implemented this [http://archive.computerhistory.org/resources/text/algol/algol_bulletin/A52/P43.HTM man boy test] in [[ALGOL 68]], and - as call by name is not necessary - the same algorithm can be implemented in many languages including [[:Category:Pascal|Pascal]] and [[:Category:PL/I|PL/I]] <!-- <ref>{{cite web|title=Block Structure and Environments | author=[[Charles H. Lindsey]] | url=http://archive.computerhistory.org/resources/text/algol/algol_bulletin/A52/P43.HTM | accessyear=2007 | accessmonthday=May 2| year=1988 | month=Dec}}</ref>. --> <!-- <ref>{{cite web|title="Man or boy" test|url=http://groups.google.com/group/comp.lang.haskell/browse_thread/thread/eef78beaaac73b26/7a6672ceea07b34e}}</ref>, -->.
<langsyntaxhighlight lang="algol68">PROC a = (INT in k, PROC INT xl, x2, x3, x4, x5) INT:(
INT k := in k;
PROC b = INT: a(k-:=1, b, xl, x2, x3, x4);
Line 460:
test:(
printf(($gl$,a(10, INT:1, INT:-1, INT:-1, INT:1, INT:0)))
)</langsyntaxhighlight>
Output:
<pre>
-67
</pre>
 
=={{header|ALGOL W}}==
{{Trans|ALGOL 60}}
Algol 60 has two parameter passing modes: by value and by name, Algol W has these plus a number of others. In Algol W, an expression is automatically converted to a procedure (by the compiler) if it is used as a parameter to a procedure that is expecting a procedure - this is used in the following. The sample below is thus similar to the Algol 68 sample above, but without the need for routine texts for the literals 1, -1, etc. as these are generated automatically.
<p>
Note that unlike Algol 60, in Algol W the result of a procedure is the final value calculated by the procedure and so the result cannot be assigned in a sub-procedure. This means the following sample is "strictly incorrect" (see the notes on the Algol 60 sample) but yields the correct result.
<syntaxhighlight lang="algolw">begin
real procedure A (integer value k; real procedure x1, x2, x3, x4, x5);
begin
real procedure B;
begin k:= k - 1;
A (k, B, x1, x2, x3, x4)
end;
if k <= 0 then x4 + x5 else B
end;
write (r_format := "A", r_w := 8, r_d := 2, A (10, 1, -1, -1, 1, 0))
end.</syntaxhighlight>
{{out}}
<pre>
-67.00
</pre>
 
Line 471 ⟶ 492:
AppleScript's stack limit is around 500 frames, which is too low to run this example. It runs in the compatible [http://en.wikipedia.org/wiki/Smile_%28software%29 Smile] environment, however.
 
<langsyntaxhighlight lang="applescript">on a(k, x1, x2, x3, x4, x5)
script b
set k to k - 1
Line 491 ⟶ 512:
 
a(10, int(1), int(-1), int(-1), int(1), int(0))
</syntaxhighlight>
</lang>
Output:
<pre>
Line 497 ⟶ 518:
</pre>
 
=={{header|BBC BASIC}}==
==={{header|BBC BASIC}}===
{{works with|BBC BASIC for Windows}}
<langsyntaxhighlight lang="bbcbasic"> HIMEM = PAGE + 200000000 : REM Increase recursion depth
FOR k% = 0 TO 20
Line 523 ⟶ 545:
DEF FN0(d%) = 0
DEF FN1(d%) = 1
DEF FN_1(d%) = -1</langsyntaxhighlight>
Output:
<pre>
Line 553 ⟶ 575:
Even if [[closures]] are not available in a language, their effect can be simulated. This is what happens in the following C implementation:
 
<langsyntaxhighlight lang="c">/* man-or-boy.c */
#include <stdio.h>
#include <stdlib.h>
Line 595 ⟶ 617:
MAKE_ARG(f1), MAKE_ARG(f0))));
return 0;
}</langsyntaxhighlight>
 
Two gcc extensions to the C language, nested functions and block sub-expressions, can be combined to create this elegant version:
 
Version: gcc version 4.1.2 20070925 (Red Hat 4.1.2-27)
<langsyntaxhighlight lang="c">#include <stdio.h>
#define INT(body) ({ int lambda(){ body; }; lambda; })
main(){
Line 610 ⟶ 632:
}
printf(" %d\n",a(10, INT(return 1), INT(return -1), INT(return -1), INT(return 1), INT(return 0)));
}</langsyntaxhighlight>
 
C without C99 or gcc extensions:
 
<langsyntaxhighlight lang="c">#include <stdio.h>
#include <stdlib.h>
Line 660 ⟶ 682:
printf("%d\n", A(Frame(&a, &k, &f1, &fn1, &fn1, &f1, &f0)));
return 0;
}</langsyntaxhighlight>
 
Output:
-67
 
=={{header|C sharp|C#}}==
C# 2.0 supports anonymous methods which are used in the implementation below:
 
{{works with|C sharp|C#|2+}}
 
<syntaxhighlight lang="csharp">using System;
delegate T Func<T>();
class ManOrBoy
{
static void Main()
{
Console.WriteLine(A(10, C(1), C(-1), C(-1), C(1), C(0)));
}
static Func<int> C(int i)
{
return delegate { return i; };
}
static int A(int k, Func<int> x1, Func<int> x2, Func<int> x3, Func<int> x4, Func<int> x5)
{
Func<int> b = null;
b = delegate { k--; return A(k, b, x1, x2, x3, x4); };
return k <= 0 ? x4() + x5() : b();
}
}
</syntaxhighlight>
 
C# 3.0 supports lambda expressions which are used in the implementation below:
 
{{works with|C sharp|C#|3+}}
 
<syntaxhighlight lang="csharp">using System;
class ManOrBoy
{
static void Main()
{
Console.WriteLine(A(10, () => 1, () => -1, () => -1, () => 1, () => 0));
}
static int A(int k, Func<int> x1, Func<int> x2, Func<int> x3, Func<int> x4, Func<int> x5)
{
Func<int> b = null;
b = () => { k--; return A(k, b, x1, x2, x3, x4); };
return k <= 0 ? x4() + x5() : b();
}
}</syntaxhighlight>
 
=={{header|C++}}==
Line 670 ⟶ 743:
Uses "shared_ptr" smart pointers from Boost / TR1 to automatically deallocate objects. Since we have an object which needs to pass a pointer to itself to another function, we need to use "enable_shared_from_this".
 
<langsyntaxhighlight lang="cpp">#include <iostream>
#include <tr1/memory>
using std::tr1::shared_ptr;
Line 722 ⟶ 795:
shared_ptr<Arg>(new Const(0))) << std::endl;
return 0;
}</langsyntaxhighlight>
 
{{works with|C++11}} uses anonymous functions. Tested with g++ version 4.5 and Visual C++ version 16 (Windows SDK 7.1):
<langsyntaxhighlight lang="cpp">#include <functional>
#include <iostream>
 
Line 749 ⟶ 822:
std::cout << A(10, L(1), L(-1), L(-1), L(1), L(0)) << std::endl;
return 0;
}</langsyntaxhighlight>
 
{{works with|TR1}} uses TR1 without C++11.
<langsyntaxhighlight lang="cpp">#include <tr1/functional>
#include <iostream>
 
Line 783 ⟶ 856:
std::cout << A(10, L(1), L(-1), L(-1), L(1), L(0)) << std::endl;
return 0;
}</langsyntaxhighlight>
 
=={{header|C sharp|C#}}==
C# 2.0 supports anonymous methods which are used in the implementation below:
 
{{works with|C sharp|C#|2+}}
 
<lang csharp>using System;
delegate T Func<T>();
class ManOrBoy
{
static void Main()
{
Console.WriteLine(A(10, C(1), C(-1), C(-1), C(1), C(0)));
}
static Func<int> C(int i)
{
return delegate { return i; };
}
static int A(int k, Func<int> x1, Func<int> x2, Func<int> x3, Func<int> x4, Func<int> x5)
{
Func<int> b = null;
b = delegate { k--; return A(k, b, x1, x2, x3, x4); };
return k <= 0 ? x4() + x5() : b();
}
}
</lang>
 
C# 3.0 supports lambda expressions which are used in the implementation below:
 
{{works with|C sharp|C#|3+}}
 
<lang csharp>using System;
class ManOrBoy
{
static void Main()
{
Console.WriteLine(A(10, () => 1, () => -1, () => -1, () => 1, () => 0));
}
static int A(int k, Func<int> x1, Func<int> x2, Func<int> x3, Func<int> x4, Func<int> x5)
{
Func<int> b = null;
b = () => { k--; return A(k, b, x1, x2, x3, x4); };
return k <= 0 ? x4() + x5() : b();
}
}</lang>
 
=={{header|Clipper}}==
 
<langsyntaxhighlight Clipperlang="clipper">Procedure Main()
Local k
For k := 0 to 20
Line 862 ⟶ 884:
xVal := x
Endif
Return xVal</langsyntaxhighlight>
 
 
Line 896 ⟶ 918:
=={{header|Clojure}}==
 
<langsyntaxhighlight lang="lisp">(declare a)
 
(defn man-or-boy
Line 920 ⟶ 942:
 
(man-or-boy 10)
</syntaxhighlight>
</lang>
 
=={{header|Common Lisp}}==
 
<langsyntaxhighlight lang="lisp">(defun man-or-boy (x)
(a x (lambda () 1)
(lambda () -1)
Line 939 ⟶ 961:
(b))))
 
(man-or-boy 10)</langsyntaxhighlight>
 
=={{header|Crystal}}==
<langsyntaxhighlight lang="ruby">def a(k, x1, x2, x3, x4, x5)
b = uninitialized -> typeof(k)
b = ->() { k -= 1; a(k, b, x1, x2, x3, x4) }
Line 948 ⟶ 970:
end
 
puts a(10, -> {1}, -> {-1}, -> {-1}, -> {1}, -> {0})</langsyntaxhighlight>
{{out}}
<pre>
Line 956 ⟶ 978:
=={{header|D}}==
===Straightforward Version===
<langsyntaxhighlight lang="d">import core.stdc.stdio: printf;
 
int a(int k, const lazy int x1, const lazy int x2, const lazy int x3,
Line 969 ⟶ 991:
void main() {
printf("%d\n", a(10, 1, -1, -1, 1, 0));
}</langsyntaxhighlight>
The DMD compiler is a man. Increasing the maximum stack space to about 1.2 GB the DMD 2.059 compiler computes the result -9479595 for k = 25 in about 6.5 seconds on a 32 bit system (-inline -O -release -L/STACK:1300000000).
 
Line 975 ⟶ 997:
[http://www.digitalmars.com/d/1.0/function.html Lazy Variadic Functions] version, as quoted:<br>
:If the variadic parameter is an array of delegates with no parameters:<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;void foo(int delegate()[] dgs ...);</tt><br>Then each of the arguments whose type does not match that of the delegate is converted to a delegate.<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;int delegate() dg;</tt><br><tt>&nbsp;&nbsp;&nbsp;&nbsp;foo(1, 3+x, dg, cast(int delegate())null);</tt><br>is the same as:<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;foo( { return 1; }, { return 3+x; }, dg, null );</tt><br>
<langsyntaxhighlight lang="d">int A(int k, int delegate() nothrow @safe[] x...) nothrow @safe {
int b() nothrow @safe {
k--;
Line 988 ⟶ 1,010:
 
A(10, 1, -1, -1, 1, 0).writeln;
}</langsyntaxhighlight>
 
===Template Version===
<langsyntaxhighlight lang="d">auto mb(T)(T mob) nothrow @safe { // Embeding function.
int b() nothrow @safe @nogc {
static if (is(T == int))
Line 1,018 ⟶ 1,040:
 
A(10, 1, -1, -1, 1, 0).writeln;
}</langsyntaxhighlight>
 
===Anonymous Class Version===
Similar to Java example:
<langsyntaxhighlight lang="d">import std.stdio;
 
interface B {
Line 1,061 ⟶ 1,083:
void main() {
writeln(A(10, 1, -1, -1, 1, 0));
}</langsyntaxhighlight>
 
===Faster Version===
This version cheats, using a different much faster algorithm.
<langsyntaxhighlight lang="d">import std.bigint, std.functional;
 
// Adapted from C code by Goran Weinholt, adapted from Knuth code.
Line 1,121 ⟶ 1,143:
writefln("...\n500 %-(%s\\\n %)",
A(500, 1, -1, -1, 1, 0).text.chunks(60));
}</langsyntaxhighlight>
{{out}}
<pre>0 1
Line 1,172 ⟶ 1,194:
The latest editions of Delphi support anonymous methods, providing a way to implement call by name semantics.
 
<langsyntaxhighlight lang="delphi">type
TFunc<T> = reference to function: T;
Line 1,200 ⟶ 1,222:
begin
Writeln(A(10, C(1), C(-1), C(-1), C(1), C(0))); // -67 output
end.</langsyntaxhighlight>
 
=={{header|Déjà Vu}}==
 
{{trans|Python}}
 
<lang dejavu>a k x1 x2 x3 x4 x5:
local b:
set :k -- k
a k @b @x1 @x2 @x3 @x4
if <= k 0:
+ x4 x5
else:
b
local x i:
labda:
i
 
!. a 10 x 1 x -1 x -1 x 1 x 0</lang>
 
=={{header|Dyalect}}==
 
<langsyntaxhighlight Dyalectlang="dyalect">func C_C(i) {
() => i
}
func A_A(k, x1, x2, x3, x4, x5) {
var b
b = () => {
k -= 1
A_A(k, b, x1, x2, x3, x4)
}
if k <= 0 {
Line 1,238 ⟶ 1,242:
}
}
 
for i in 1..20 {
print(A(12, C(1), C(-1), C(-1), C(1), C(0)))</lang>
let res = _A(i, _C(1), _C(-1), _C(-1), _C(1), _C(0))
print("\(i)\t= \(res)")
}</syntaxhighlight>
 
{{out}}
 
<pre>-291</pre>1 = 0
2 = -2
3 = 0
4 = 1
5 = 0
6 = 1
7 = -1
8 = -10
9 = -30
10 = -67
11 = -138
12 = -291
13 = -642
14 = -1446
15 = -3250
16 = -7244
17 = -16065
18 = -35601
19 = -78985
20 = -175416</pre>
 
=={{header|Dylan}}==
<langsyntaxhighlight lang="dylan">define method a
(k :: <integer>, x1 :: <function>, x2 :: <function>, x3 :: <function>,
x4 :: <function>, x5 :: <function>)
Line 1,272 ⟶ 1,298:
end method man-or-boy;
 
format-out("%d\n", man-or-boy(10))</langsyntaxhighlight>
 
=={{header|Déjà Vu}}==
 
{{trans|Python}}
 
<syntaxhighlight lang="dejavu">a k x1 x2 x3 x4 x5:
local b:
set :k -- k
a k @b @x1 @x2 @x3 @x4
if <= k 0:
+ x4 x5
else:
b
local x i:
labda:
i
 
!. a 10 x 1 x -1 x -1 x 1 x 0</syntaxhighlight>
 
=={{header|E}}==
Line 1,278 ⟶ 1,322:
Provided that it is marked in the caller and callee, E can perfectly emulate the requested [[wp:Call-by-name#Call_by_name|call-by-name]] behavior by passing slots instead of values:
 
<langsyntaxhighlight lang="e">def a(var k, &x1, &x2, &x3, &x4, &x5) {
def bS; def &b := bS
bind bS {
Line 1,292 ⟶ 1,336:
def n := -1
def z := 0
println(a(10, &p, &n, &n, &p, &z))</langsyntaxhighlight>
 
Here each of the "<code>x</code>" parameters is effectively call-by-name. <var><code>b</code></var> is bound to a custom slot definition.
 
=={{header|EchoLisp}}==
<langsyntaxhighlight lang="scheme">
;; copied from Scheme
(define (A k x1 x2 x3 x4 x5)
Line 1,314 ⟶ 1,358:
❗ InternalError : too much recursion - JS internal error (please, report it)-
→ stack overflow using FireFox
</syntaxhighlight>
</lang>
 
 
=={{header|Ela}}==
Line 1,321 ⟶ 1,364:
Stack overflow is not a problem in Ela (but "out of memory" is):
 
<langsyntaxhighlight lang="ela">open monad io unsafe.cell unsafe.console
 
liftM2 f m1 m2 = do
Line 1,335 ⟶ 1,378:
 
_ = a 10 (!!1) (!! -1) (!! -1) (!!1) (!!0) >>= (putStr << show) ::: IO
where (!!) f = & return f ::: IO</langsyntaxhighlight>
 
=={{header|Elena}}==
ELENA 46.x:
<langsyntaxhighlight lang="elena">import extensions;
 
A(k,x1,x2,x3,x4,x5)
{
var m := new Integerref<int>(k);
var b := (){ m.reduce:1; ^ A(m,this self,x1,x2,x3,x4) };
var b := { m -= 1; ^ A(m,this self,x1,x2,x3,x4) };
if (m <= 0)
Line 1,358 ⟶ 1,402:
public program()
{
for(int n := 0,; n <= 14,; n += 1)
{
console.printLine(A(n,({^1)},({^-1)},({^-1)},({^1)},({^0)}))
}
}</langsyntaxhighlight>
{{out}}
<pre>
Line 1,380 ⟶ 1,424:
-642
-1446
</pre>
 
=={{header|Elixir}}==
The solution is gracefully stolen from Erlang one (see below).
<pre>
kounter = fn k, kounter ->
receive do
{:decr, pid} ->
send(pid, k - 1)
kounter.(k - 1, kounter)
_ -> :ok
end
end
 
a = fn k, x1, x2, x3, x4, x5, a ->
kounter_process = spawn(fn -> kounter.(k, kounter) end)
b =
fn b ->
send(kounter_process, {:decr, self()})
receive do
pred -> a.(pred, fn -> b.(b) end, x1, x2, x3, x4, a)
end
end
 
if k <= 0,
do: send(kounter_process, x4.() + x5.()),
else: send(kounter_process, b.(b))
end
 
man_or_boy = fn n ->
a.(n, fn -> 1 end, fn -> -1 end, fn -> -1 end, fn -> 1 end, fn -> 0 end, a)
end
 
▶ man_or_boy.(10) #⇒ -67
▶ man_or_boy.(14) #⇒ -1446
▶ man_or_boy.(20) #⇒ [error] Too many processes
</pre>
 
=={{header|EMal}}==
<syntaxhighlight lang="emal">
fun A = int by int k, fun x1, fun x2, fun x3, fun x4, fun x5
fun B = int by block do return A(--k, B, x1, x2, x3, x4) end
return when(k <= 0, x4() + x5(), B())
end
fun C = fun by int i
return int by block do return i end
end
for int i = 0; i <= 11; i++
writeLine("A(" + i + ") = " + A(i, C(1), C(-1), C(-1), C(1), C(0) ))
end
</syntaxhighlight>
{{out}}
<pre>
A(0) = 1
A(1) = 0
A(2) = -2
A(3) = 0
A(4) = 1
A(5) = 0
A(6) = 1
A(7) = -1
A(8) = -10
A(9) = -30
A(10) = -67
A(11) = -138
</pre>
 
Line 1,413 ⟶ 1,523:
Straightforward version:
 
<langsyntaxhighlight lang="fsharp">
[<EntryPoint>]
let main (args : string[]) =
Line 1,434 ⟶ 1,544:
 
0
</syntaxhighlight>
</lang>
 
Using a trampoline to avoid stack overflows when k >= 20:
 
<langsyntaxhighlight lang="fsharp">
type Tramp<'t> =
| Delay of (unit -> Tramp<'t>)
Line 1,494 ⟶ 1,604:
 
0
</syntaxhighlight>
</lang>
 
F# supports tail calls (when compiled in Release mode), so you can also avoid stack overflow using the straightforward approach modified to use continuation-passing style:
<syntaxhighlight lang="fsharp">
[<EntryPoint>]
let main (args : string[]) =
let k = int(args.[0])
 
let l x cont = cont x
 
let rec a k x1 x2 x3 x4 x5 cont =
if k <= 0 then
x4 (fun n4 -> x5 (fun n5 -> cont (n4+n5)))
else
let mutable k = k
let rec b cont =
k <- k - 1
a k b x1 x2 x3 x4 cont
b cont
 
a k (l 1) (l -1) (l -1) (l 1) (l 0) (printfn "%d")
 
0
</syntaxhighlight>
 
 
=={{header|Fantom}}==
Fantom has closures, so:
 
<syntaxhighlight lang="fantom">
<lang Fantom>
class ManOrBoy
{
Line 1,514 ⟶ 1,648:
}
}
</syntaxhighlight>
</lang>
 
yields
Line 1,520 ⟶ 1,654:
-67
</pre>
 
 
=={{header|Forth}}==
Line 1,527 ⟶ 1,660:
Gforth provides flat closures [{: ... :}L ... ;] that are initialized from the stack. You have to perform flat-closure conversion and assignment conversion manually (and this has been done here).
 
<langsyntaxhighlight Forthlang="forth">: A {: w^ k x1 x2 x3 xt: x4 xt: x5 | w^ B :} recursive
k @ 0<= IF x4 x5 f+ ELSE
B k x1 x2 x3 action-of x4 [{: B k x1 x2 x3 x4 :}L
Line 1,533 ⟶ 1,666:
k @ B @ x1 x2 x3 x4 A ;] dup B !
execute THEN ;
10 [: 1e ;] [: -1e ;] 2dup swap [: 0e ;] A f. </langsyntaxhighlight>
 
=={{header|Fortran}}==
Fortran 2008 (uses an internal procedure as function argument). Tested with g95 and gfortran 4.6.
<langsyntaxhighlight Fortranlang="fortran">module man_or_boy
 
implicit none
Line 1,592 ⟶ 1,725:
use man_or_boy
write (*,*) A(10,one,minus_one,minus_one,one,zero)
end program test</langsyntaxhighlight>
 
=={{header|Go}}==
<langsyntaxhighlight lang="go">package main
import "fmt"
 
Line 1,613 ⟶ 1,746:
x := func(i int) func() int { return func() int { return i } }
fmt.Println(a(10, x(1), x(-1), x(-1), x(1), x(0)))
}</langsyntaxhighlight>
 
Another version that uses named result parameters the way the original Algol uses the function name. This includes B setting the result of its enclosing A.
<langsyntaxhighlight lang="go">package main
 
import "fmt"
Line 1,640 ⟶ 1,773:
fmt.Println(A(10, K(1), K(-1), K(-1), K(1), K(0)))
}
</syntaxhighlight>
</lang>
 
By exploiting interfaces, one can more closely parallel the original Algol's polymorphic parameters.
<langsyntaxhighlight lang="go">package main
 
import "fmt"
Line 1,676 ⟶ 1,809:
func main() {
fmt.Println(A(10, 1, -1, -1, 1, 0))
}</langsyntaxhighlight>
 
Inspired by D's "faster" version, here's another that uses a different algorithm to compute the result.
<langsyntaxhighlight lang="go">package main
 
import (
Line 1,687 ⟶ 1,820:
 
func A(k int) *big.Int {
if k < 6 {
var x1, x2, x3, x4 int64 = 1, -1, -1, 1
c1 := []int64{0, 0, 0, 1, 2, 3}[k]
c2 := []int64{0, 0, 1, 1, 1, 2}[k]
c3 := []int64{0, 1, 1, 0, 0, 1}[k]
c4 := []int64{1, 1, 0, 0, 0, 0}[k]
t := c1*x1 + c2*x2 + c3*x3 + c4*x4
return big.NewInt(t)
}
one := big.NewInt(1)
c0 := big.NewInt(3)
Line 1,712 ⟶ 1,854:
 
func main() {
for i := 0; i < 40; i++ {
p(10)
p(30i)
}
p(500)
p(10000)
p(1e6)
}</langsyntaxhighlight>
{{out}}
<pre>
A(0) = 1
A(1) = 0
A(2) = -2
A(3) = 0
A(4) = 1
A(5) = 0
A(6) = 1
A(7) = -1
A(8) = -10
A(9) = -30
A(10) = -67
A(11) = -138
A(12) = -291
A(13) = -642
A(14) = -1446
A(15) = -3250
A(16) = -7244
A(17) = -16065
A(18) = -35601
A(19) = -78985
A(20) = -175416
A(21) = -389695
A(22) = -865609
A(23) = -1922362
A(24) = -4268854
A(25) = -9479595
A(26) = -21051458
A(27) = -46750171
A(28) = -103821058
A(29) = -230560902
A(30) = -512016658
A(31) = -1137056340
A(32) = -2525108865
A(33) = -5607619809
A(34) = -12453091089
A(35) = -27655133488
A(36) = -61414977599
A(37) = -136386945105
A(38) = -302880491178
A(39) = -672620048590
A(500) = -36608...67320 (172 digits)
A(10000) = -19928...34899 (3464 digits)
Line 1,733 ⟶ 1,914:
This is not stictly identical with Wirth's example.
 
<langsyntaxhighlight lang="gosu">function A(in_k: int, x1(): int, x2(): int, x3(): int, x4(): int, x5(): int): int {
var k = in_k
var B(): int // B is a function variable
Line 1,742 ⟶ 1,923:
return k<=0 ? x4()+x5() : B()
}
print(A(10, \ -> 1, \ -> -1, \ -> -1, \ -> 1, \ -> 0))</langsyntaxhighlight>
 
Output:
Line 1,751 ⟶ 1,932:
=={{header|Groovy}}==
Solution:
<langsyntaxhighlight lang="groovy">def a; a = { k, x1, x2, x3, x4, x5 ->
def b; b = {
a (--k, b, x1, x2, x3, x4)
Line 1,758 ⟶ 1,939:
}
 
def x = { n -> { it -> n } }</langsyntaxhighlight>
 
Test 1:
<langsyntaxhighlight lang="groovy">println (a(10, x(1), x(-1), x(-1), x(1), x(0)))</langsyntaxhighlight>
 
This test overflowed the stack at the default stack size. On my system I required "-Xss1409k" or larger to run successfully.
Line 1,769 ⟶ 1,950:
 
Test 2:
<langsyntaxhighlight lang="groovy">(0..20).each { k ->
printf ("%3d: %7d\n", k, a(k, x(1), x(-1), x(-1), x(1), x(0)))
}</langsyntaxhighlight>
 
This test required "-Xss345m" to avoid overflow.
Line 1,802 ⟶ 1,983:
Haskell is a pure language, so the impure effects of updating ''k'' must be wrapped in the IO or ST [[Monads|monad]]:
 
<langsyntaxhighlight lang="haskell">import ControlData.ApplicativeIORef (liftA2modifyIORef, newIORef, readIORef)
import Data.IORef (modifyIORef, newIORef, readIORef)
 
a
Line 1,814 ⟶ 1,994:
a k b x1 x2 x3 x4
if k <= 0
then liftA2 (+) <$> x4 <*> x5
else b
where
Line 1,822 ⟶ 2,002:
main = a 10 # 1 # (-1) # (-1) # 1 # 0 >>= print
where
( # ) f = f . return</langsyntaxhighlight>
 
On an AMD Opteron 6282 SE using GHC 7.8.2 this program can compute ''k'' = 30 in 1064 s and 156.2 GiB.
Line 1,868 ⟶ 2,048:
 
The co-expression version.
<langsyntaxhighlight Iconlang="icon">record mutable(value) # we need mutable integers
# ... be obvious when we break normal scope rules
procedure main(arglist) # supply the initial k value
Line 1,890 ⟶ 2,070:
k.value -:= 1 # diddle A's copy of k
return A(k.value, create |B(k,x1,x2,x3,x4,x5),x1,x2,x3,x4) # call A with a new k and 5 x's
end</langsyntaxhighlight>
 
Below are the code changes for the non-co-expression version. A new record type is introduced and the two return expressions are changed slightly.
 
<langsyntaxhighlight Iconlang="icon">record defercall(proc,arglist) # light weight alternative to co-expr for MoB
 
procedure eval(ref) # evaluator to distinguish between a simple value and a code reference
Line 1,903 ⟶ 2,083:
k.value -:= 1 # diddle A's copy of k
return A(k.value, defercall(B,[k,x1,x2,x3,x4,x5]),x1,x2,x3,x4)# call A with a new k and 5 x's
end</langsyntaxhighlight>
 
=={{Headerheader|Io}}==
 
Io is nothing if not aggressively manly.
 
<langsyntaxhighlight lang="io">Range
 
a := method(k, xs,
Line 1,922 ⟶ 2,102:
1 to(500) foreach(k,
(k .. " ") print
a(k, list(1, -1, -1, 1, 0) map (x, f(x))) println)</langsyntaxhighlight>
 
=={{header|J}}==
Line 1,928 ⟶ 2,108:
Given
 
<langsyntaxhighlight Jlang="j">A=:4 :0
L=.cocreate'' NB. L is context where names are defined.
k__L=:x
Line 1,940 ⟶ 2,120:
k__L=:k__L-1
a__L=:k__L A L&B`(x1__L f.)`(x2__L f.)`(x3__L f.)`(x4__L f.)
)</langsyntaxhighlight>
 
 
<langsyntaxhighlight Jlang="j"> 10 A 1:`_1:`_1:`1:`0:
_67</langsyntaxhighlight>
 
=={{header|Java}}==
Line 1,952 ⟶ 2,132:
Java Version 8 and up
 
<langsyntaxhighlight lang="java">import java.util.function.DoubleSupplier;
 
public class ManOrBoy {
Line 1,972 ⟶ 2,152:
System.out.println(A(10, () -> 1.0, () -> -1.0, () -> -1.0, () -> 1.0, () -> 0.0));
}
}</langsyntaxhighlight>
 
Java Version 7
 
<langsyntaxhighlight lang="java">public class ManOrBoy {
interface Arg {
public int run();
Line 2,002 ⟶ 2,182:
System.out.println(A(10, C(1), C(-1), C(-1), C(1), C(0)));
}
}</langsyntaxhighlight>
 
=={{header|JavaScript}}==
In Chrome we get a "Maximum call stack size exceeded" when a > 13. In Firefox we get "too much recursion" when a > 12.
<langsyntaxhighlight lang="javascript">function a(k, x1, x2, x3, x4, x5) {
function b() {
k -= 1;
Line 2,020 ⟶ 2,200:
};
}
alert(a(10, x(1), x(-1), x(-1), x(1), x(0)));</langsyntaxhighlight>
 
Implemented using ES6 syntax
<langsyntaxhighlight lang="javascript">var x = n => () => n;
 
var a = (k, x1, x2, x3, x4, x5) => {
var b = () => return a(--k, b, x1, x2, x3, x4); //decrement k before use
return (k > 0) ? b() : x4() + x5();
};</langsyntaxhighlight>
 
=={{header|Jsish}}==
From Javascript entry.
<langsyntaxhighlight lang="javascript">/* Knuth's Man or boy test (local references in recursion), in Jsish */
/* As noted, needs a fair sized stack depth, default is 200 in jsish v2.8.24 */
Interp.conf({maxDepth:2048});
Line 2,057 ⟶ 2,237:
-67
=!EXPECTEND!=
*/</langsyntaxhighlight>
 
{{out}}
Line 2,066 ⟶ 2,246:
 
=={{header|Julia}}==
<langsyntaxhighlight lang="julia">function a(k, x1, x2, x3, x4, x5)
b = ()-> a(k-=1, b, x1, x2, x3, x4);
k <= 0 ? (x4() + x5()) : b();
end
 
println(a(10, ()->1, ()->-1, ()->-1, ()->1, ()->0));</langsyntaxhighlight>
 
=={{header|Kotlin}}==
Using the default JVM stack size, could only get to k = 12 before experiencing an overflow:
<langsyntaxhighlight lang="scala">// version 1.1.3
 
typealias Func = () -> Int
Line 2,091 ⟶ 2,271:
}
}
</syntaxhighlight>
</lang>
 
{{out}}
Line 2,112 ⟶ 2,292:
 
=={{header|Lox}}==
<langsyntaxhighlight lang="lox">fun A (k, xa, xb, xc, xd, xe) {
print k;
fun B() {
Line 2,129 ⟶ 2,309:
fun I_1() { return -1; }
 
print A(10, I1, I_1, I_1, I1, I0);</langsyntaxhighlight>
 
=={{header|Lua}}==
 
<langsyntaxhighlight lang="lua">function a(k,x1,x2,x3,x4,x5)
local function b()
k = k - 1
Line 2,147 ⟶ 2,327:
end
print(a(10, K(1), K(-1), K(-1), K(1), K(0)))</langsyntaxhighlight>
 
=={{header|Mathematica}}==
 
=={{header|Mathematica}}/{{header|Wolfram Language}}==
This ''Mathematica'' code was derived from the Ruby example appearing below.
<syntaxhighlight lang="mathematica">$RecursionLimit = 1665; (* anything less fails for k0 = 10 *)
 
$RecursionLimit = 1665; (* anything less fails for k0 = 10 *)
a[k0_, x1_, x2_, x3_, x4_, x5_] := Module[{k, b },
k = k0;
b = (k--; a[k, b, x1, x2, x3, x4]) &;
If[k <= 0, x4[] + x5[], b[]]]
a[10, 1 &, -1 &, -1 &, 1 &, 0 &]</syntaxhighlight>
 
{{out}}
a[10, 1 &, -1 &, -1 &, 1 &, 0 &] (* => -67 *)
<pre>-67</pre>
 
=={{header|Modula-3}}==
 
<langsyntaxhighlight lang="modula3">MODULE Main;
IMPORT IO;
 
Line 2,192 ⟶ 2,370:
IO.PutInt(A(10, F1, Fn1, Fn1, F1, F0));
IO.Put("\n");
END Main.</langsyntaxhighlight>
 
=={{header|Nim}}==
With standard compilation values, it is possible to run the program with <code>k = 10</code>. With <code>k = 11</code>, we reach the default call depth limit (2000). In this case, compiling with option <code>-d:nimCallDepthLimit=2100</code> is enough to get the result: -138.
<lang nim>import future
<syntaxhighlight lang="nim">import sugar
 
proc a(k: int; x1, x2, x3, x4, x5: proc(): int): int =
Line 2,205 ⟶ 2,384:
else: b()
 
echo a(10, () => 1, () => -1, () => -1, () => 1, () => 0)</langsyntaxhighlight>
 
{{out}}
<pre>-67</pre>
 
=={{header|Objeck}}==
Using anonymous classes instead of closures
<syntaxhighlight lang="objeck">interface Arg {
method : virtual : public : Run() ~ Int;
}
 
class ManOrBoy {
New() {}
function : A(mb : ManOrBoy, k : Int, x1 : Arg, x2 : Arg, x3 : Arg, x4 : Arg, x5 : Arg) ~ Int {
if(k <= 0) {
return x4->Run() + x5->Run();
};
return Base->New(mb, k, x1, x2, x3, x4) implements Arg {
@mb : ManOrBoy; @k : Int; @x1 : Arg; @x2 : Arg; @x3 : Arg; @x4 : Arg; @m : Int;
New(mb : ManOrBoy, k : Int, x1 : Arg, x2 : Arg, x3 : Arg, x4 : Arg) {
@mb := mb; @k := k; @x1 := x1; @x2 := x2; @x3 := x3; @x4 := x4; @m := @k;
}
method : public : Run() ~ Int {
@m -= 1;
return @mb->A(@mb, @m, @self, @x1, @x2, @x3, @x4);
}
}->Run();
}
function : C(i : Int) ~ Arg {
return Base->New(i) implements Arg {
@i : Int;
New(i : Int) {
@i := i;
}
method : public : Run() ~ Int {
return @i;
}
};
}
function : Main(args : String[]) ~ Nil {
mb := ManOrBoy->New();
mb->A(mb, 10, C(1), C(-1), C(-1), C(1), C(0))->PrintLine();
}
}
</syntaxhighlight>
 
=={{header|Objective-C}}==
{{works with|Cocoa|Mac OS X 10.6+}}
<langsyntaxhighlight lang="objc">#import <Foundation/Foundation.h>
 
typedef NSInteger (^IntegerBlock)(void);
Line 2,233 ⟶ 2,463:
}
return 0;
}</langsyntaxhighlight>
 
Without ARC, the above should be:
<langsyntaxhighlight lang="objc">#import <Foundation/Foundation.h>
 
typedef NSInteger (^IntegerBlock)(void);
Line 2,259 ⟶ 2,489:
[pool drain];
return 0;
}</langsyntaxhighlight>
 
 
without Blocks or ARC:
<langsyntaxhighlight lang="objc">@protocol IntegerFun <NSObject>
-(NSInteger)call;
@end
Line 2,335 ⟶ 2,565:
[pool release];
return 0;
}</langsyntaxhighlight>
 
=={{header|Objeck}}==
Using anonymous classes instead of closures
<lang objeck>interface Arg {
method : virtual : public : Run() ~ Int;
}
 
class ManOrBoy {
New() {}
function : A(mb : ManOrBoy, k : Int, x1 : Arg, x2 : Arg, x3 : Arg, x4 : Arg, x5 : Arg) ~ Int {
if(k <= 0) {
return x4->Run() + x5->Run();
};
return Base->New(mb, k, x1, x2, x3, x4) implements Arg {
@mb : ManOrBoy; @k : Int; @x1 : Arg; @x2 : Arg; @x3 : Arg; @x4 : Arg; @m : Int;
New(mb : ManOrBoy, k : Int, x1 : Arg, x2 : Arg, x3 : Arg, x4 : Arg) {
@mb := mb; @k := k; @x1 := x1; @x2 := x2; @x3 := x3; @x4 := x4; @m := @k;
}
method : public : Run() ~ Int {
@m -= 1;
return @mb->A(@mb, @m, @self, @x1, @x2, @x3, @x4);
}
}->Run();
}
function : C(i : Int) ~ Arg {
return Base->New(i) implements Arg {
@i : Int;
New(i : Int) {
@i := i;
}
method : public : Run() ~ Int {
return @i;
}
};
}
function : Main(args : String[]) ~ Nil {
mb := ManOrBoy->New();
mb->A(mb, 10, C(1), C(-1), C(-1), C(1), C(0))->PrintLine();
}
}
</lang>
 
=={{header|OCaml}}==
Line 2,389 ⟶ 2,571:
OCaml variables are not mutable, so "k" is wrapped in a mutable object, which we access through a reference type called "ref".
 
<langsyntaxhighlight lang="ocaml">let rec a k x1 x2 x3 x4 x5 =
if k <= 0 then
x4 () + x5 ()
Line 2,401 ⟶ 2,583:
 
let () =
Printf.printf "%d\n" (a 10 (fun () -> 1) (fun () -> -1) (fun () -> -1) (fun () -> 1) (fun () -> 0))</langsyntaxhighlight>
 
=={{header|Odin}}==
{{trans|C}}
Odin does not have [[closures]], so we emulate them by copying the C example.
 
<syntaxhighlight lang="odin">
package main
 
import "core:fmt"
import "core:os"
import "core:strconv"
 
Arg :: struct {
fn : proc (^Arg) -> int,
k : ^int,
x1, x2, x3, x4, x5 : ^Arg,
}
 
B :: proc (a : ^Arg) -> int {
a.k^ -= 1
k := a.k^
return A(&Arg { fn = B, k = &k, x1 = a, x2 = a.x1, x3 = a.x2, x4 = a.x3, x5 = a.x4 } )
}
 
A :: proc (a : ^Arg) -> int {
return a.x4->fn() + a.x5->fn() if a.k^ <= 0 else B(a)
}
 
main :: proc () {
f_1 :: proc (^Arg) -> int { return -1 }
f0 :: proc (^Arg) -> int { return 0 }
f1 :: proc (^Arg) -> int { return 1 }
 
k := strconv.atoi(os.args[1]) if len(os.args) == 2 else 10
fmt.println(A(&Arg { fn = B, k = &k, x1 = &Arg { fn = f1 }, x2 = &Arg { fn = f_1 }, x3 = &Arg { fn = f_1 }, x4 = &Arg { fn = f1 }, x5 = &Arg { fn = f0 } }))
}
</syntaxhighlight>
 
=={{header|Ol}}==
Line 2,408 ⟶ 2,627:
But! For some reasons in version 1.2 a very limited mutators (set-ref!, set-car!, set-cdr!) are added; so this task can be implemented as usual. Please, be aware that mutators receives only values (small numbers, constants) or previously (before the mutating dest) declared objects.
 
<langsyntaxhighlight lang="scheme">
; Because argument "k" is a small number, it's a value, not an object.
; So we must 'pack' it in object - 'box' it; And 'unbox' when we try to get value.
Line 2,436 ⟶ 2,655:
(print (man-or-boy 15))
(print (man-or-boy 20))
</syntaxhighlight>
</lang>
Output:
<pre>
Line 2,443 ⟶ 2,662:
-175416
</pre>
 
 
=={{header|Oz}}==
Line 2,452 ⟶ 2,670:
We use explicit "return variables" to emulate the strange behaviour of the ALGOL B procedure which assigns a value to A's return value.
 
<langsyntaxhighlight lang="oz">declare
fun {A K X1 X2 X3 X4 X5}
ReturnA = {NewCell undefined}
Line 2,472 ⟶ 2,690:
end
in
{Show {A {NewCell 10} {C 1} {C ~1} {C ~1} {C 1} {C 0}}}</langsyntaxhighlight>
 
=={{header|Pascal}}==
 
<langsyntaxhighlight lang="pascal">program manorboy(output);
 
function zero: integer; begin zero := 0 end;
Line 2,500 ⟶ 2,718:
 
begin writeln(A(10, one, negone, negone, one, zero))
end.</langsyntaxhighlight>
 
=={{header|Perl}}==
<langsyntaxhighlight lang="perl">sub A {
my ($k, $x1, $x2, $x3, $x4, $x5) = @_;
my($B);
Line 2,510 ⟶ 2,728:
}
print A(10, sub{1}, sub {-1}, sub{-1}, sub{1}, sub{0} ), "\n";</langsyntaxhighlight>
<!-- $B must be declared before it is used. Otherwise it references the global variable
$B.
Line 2,516 ⟶ 2,734:
print A(10, map {my $p = \$_; sub{$$p}} 1, -1, -1, 1, 0), "\n";
-->
 
=={{header|Perl 6}}==
This solution avoids creating the closure B if $k <= 0 (that is, nearly every time).
<lang perl6>sub A($k is copy, &x1, &x2, &x3, &x4, &x5) {
$k <= 0
?? x4() + x5()
!! (my &B = { A(--$k, &B, &x1, &x2, &x3, &x4) })();
};
say A(10, {1}, {-1}, {-1}, {1}, {0});</lang>
{{out}}
<pre>-67</pre>
 
=={{header|Phix}}==
Ugh. Phix does not allow this sort of nonsense implicitly, so you have to get a bit <s>dirty</s> creative.<br>
Explicitly allocates space (which is automatically freed) for the various "k contexts". Manages up to k=23 in about 10s, but crashes on k=24.
<!--<syntaxhighlight lang="phix">-->
<lang Phix>forward function A(integer k, object x1, x2, x3, x4, x5)
<span style="color: #008080;">without</span> <span style="color: #008080;">js</span> <span style="color: #000080;font-style:italic;">-- allocate()</span>
 
<span style="color: #008080;">forward</span> <span style="color: #008080;">function</span> <span style="color: #000000;">A</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">k</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">object</span> <span style="color: #000000;">x1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">x2</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">x3</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">x4</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">x5</span><span style="color: #0000FF;">)</span>
function B(sequence s)
object {kptr,x1,x2,x3,x4} = s
<span style="color: #008080;">function</span> <span style="color: #000000;">B</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">)</span>
integer k = peek4s(kptr)-1
<span style="color: #004080;">object</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">kptr</span><span style="color: #0000FF;">,</span><span style="color: #000000;">x1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">x2</span><span style="color: #0000FF;">,</span><span style="color: #000000;">x3</span><span style="color: #0000FF;">,</span><span style="color: #000000;">x4</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">s</span>
poke4(kptr,k)
<span style="color: #004080;">integer</span> <span style="color: #000000;">k</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">peek4s</span><span style="color: #0000FF;">(</span><span style="color: #000000;">kptr</span><span style="color: #0000FF;">)-</span><span style="color: #000000;">1</span>
return A(k,{kptr,x1,x2,x3,x4},x1,x2,x3,x4)
<span style="color: #7060A8;">poke4</span><span style="color: #0000FF;">(</span><span style="color: #000000;">kptr</span><span style="color: #0000FF;">,</span><span style="color: #000000;">k</span><span style="color: #0000FF;">)</span>
end function
<span style="color: #008080;">return</span> <span style="color: #000000;">A</span><span style="color: #0000FF;">(</span><span style="color: #000000;">k</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">kptr</span><span style="color: #0000FF;">,</span><span style="color: #000000;">x1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">x2</span><span style="color: #0000FF;">,</span><span style="color: #000000;">x3</span><span style="color: #0000FF;">,</span><span style="color: #000000;">x4</span><span style="color: #0000FF;">},</span><span style="color: #000000;">x1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">x2</span><span style="color: #0000FF;">,</span><span style="color: #000000;">x3</span><span style="color: #0000FF;">,</span><span style="color: #000000;">x4</span><span style="color: #0000FF;">)</span>
 
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
function A(integer k, object x1, x2, x3, x4, x5)
if k<=0 then
<span style="color: #008080;">function</span> <span style="color: #000000;">A</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">k</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">object</span> <span style="color: #000000;">x1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">x2</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">x3</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">x4</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">x5</span><span style="color: #0000FF;">)</span>
return iff(sequence(x4)?B(x4):x4)+
<span style="color: #008080;">if</span> <span style="color: #000000;">k</span><span style="color: #0000FF;"><=</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span>
iff(sequence(x5)?B(x5):x5)
<span style="color: #008080;">return</span> <span style="color: #008080;">iff</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span><span style="color: #0000FF;">(</span><span style="color: #000000;">x4</span><span style="color: #0000FF;">)?</span><span style="color: #000000;">B</span><span style="color: #0000FF;">(</span><span style="color: #000000;">x4</span><span style="color: #0000FF;">):</span><span style="color: #000000;">x4</span><span style="color: #0000FF;">)+</span>
end if
<span style="color: #008080;">iff</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span><span style="color: #0000FF;">(</span><span style="color: #000000;">x5</span><span style="color: #0000FF;">)?</span><span style="color: #000000;">B</span><span style="color: #0000FF;">(</span><span style="color: #000000;">x5</span><span style="color: #0000FF;">):</span><span style="color: #000000;">x5</span><span style="color: #0000FF;">)</span>
atom kptr = allocate(4,1)
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
poke4(kptr,k)
<span style="color: #004080;">atom</span> <span style="color: #000000;">kptr</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">allocate</span><span style="color: #0000FF;">(</span><span style="color: #000000;">4</span><span style="color: #0000FF;">,</span><span style="color: #000000;">1</span><span style="color: #0000FF;">)</span>
return B({kptr,x1,x2,x3,x4})
<span style="color: #7060A8;">poke4</span><span style="color: #0000FF;">(</span><span style="color: #000000;">kptr</span><span style="color: #0000FF;">,</span><span style="color: #000000;">k</span><span style="color: #0000FF;">)</span>
end function
<span style="color: #008080;">return</span> <span style="color: #000000;">B</span><span style="color: #0000FF;">({</span><span style="color: #000000;">kptr</span><span style="color: #0000FF;">,</span><span style="color: #000000;">x1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">x2</span><span style="color: #0000FF;">,</span><span style="color: #000000;">x3</span><span style="color: #0000FF;">,</span><span style="color: #000000;">x4</span><span style="color: #0000FF;">})</span>
 
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
for k=0 to 10 do
?{"k=",k,A(k,1,-1,-1,1,0)}
<span style="color: #008080;">for</span> <span style="color: #000000;">k</span><span style="color: #0000FF;">=</span><span style="color: #000000;">0</span> <span style="color: #008080;">to</span> <span style="color: #000000;">23</span> <span style="color: #008080;">do</span>
end for</lang>
<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;">"A(%d) = %d\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">k</span><span style="color: #0000FF;">,</span><span style="color: #000000;">A</span><span style="color: #0000FF;">(</span><span style="color: #000000;">k</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: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">0</span><span style="color: #0000FF;">)})</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<!--</syntaxhighlight>-->
{{out}}
<pre>
A(0) = 1
{"k=",0,1}
A(1) = 0
{"k=",1,0}
{"k=",A(2,) = -2}
A(3) = 0
{"k=",3,0}
A(4) = 1
{"k=",4,1}
A(5) = 0
{"k=",5,0}
A(6) = 1
{"k=",6,1}
{"k=",A(7,) = -1}
{"k=",A(8,) = -10}
{"k=",A(9,) = -30}
{"k=",A(10,) = -67}
A(11) = -138
A(12) = -291
A(13) = -642
A(14) = -1446
A(15) = -3250
A(16) = -7244
A(17) = -16065
A(18) = -35601
A(19) = -78985
A(20) = -175416
A(21) = -389695
A(22) = -865609
A(23) = -1922362
</pre>
While the above will not run under pwa/p2js, the following translation of <del>D (Faster Version)</del> Go is fine, and rather fast.
<!--<syntaxhighlight lang="phix">(phixonline)-->
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
<span style="color: #008080;">constant</span> <span style="color: #000000;">first5</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,-</span><span style="color: #000000;">2</span><span style="color: #0000FF;">,</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">1</span><span style="color: #0000FF;">}</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">A</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">k</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">k</span><span style="color: #0000FF;"><</span><span style="color: #000000;">5</span> <span style="color: #008080;">then</span> <span style="color: #008080;">return</span> <span style="color: #000000;">first5</span><span style="color: #0000FF;">[</span><span style="color: #000000;">k</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;">if</span>
<span style="color: #004080;">atom</span> <span style="color: #000000;">c0</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">3</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">c1</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">2</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">c2</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">c3</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">j</span><span style="color: #0000FF;">=</span><span style="color: #000000;">5</span> <span style="color: #008080;">to</span> <span style="color: #000000;">k</span><span style="color: #0000FF;">-</span><span style="color: #000000;">1</span> <span style="color: #008080;">do</span>
<span style="color: #000000;">c3</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">c0</span><span style="color: #0000FF;">-</span><span style="color: #000000;">1</span>
<span style="color: #000000;">c0</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">c1</span>
<span style="color: #000000;">c1</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">c2</span>
<span style="color: #000000;">c2</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">c3</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #008080;">return</span> <span style="color: #000000;">c0</span><span style="color: #0000FF;">-</span><span style="color: #000000;">c1</span><span style="color: #0000FF;">-</span><span style="color: #000000;">c2</span><span style="color: #0000FF;">+</span><span style="color: #000000;">c3</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">k</span><span style="color: #0000FF;">=</span><span style="color: #000000;">0</span> <span style="color: #008080;">to</span> <span style="color: #000000;">40</span> <span style="color: #008080;">do</span>
<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 %d\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">k</span><span style="color: #0000FF;">,</span><span style="color: #000000;">A</span><span style="color: #0000FF;">(</span><span style="color: #000000;">k</span><span style="color: #0000FF;">)})</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<!--</syntaxhighlight>-->
{{out}}
<pre>
...
10 -67
...
20 -175416
...
30 -512016658
...
40 -1493716995219
</pre>
And the same converted to use gmp:
<!--<syntaxhighlight lang="phix">(phixonline)-->
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
<span style="color: #008080;">include</span> <span style="color: #004080;">mpfr</span><span style="color: #0000FF;">.</span><span style="color: #000000;">e</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">A</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">k</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">k</span><span style="color: #0000FF;"><</span><span style="color: #000000;">5</span> <span style="color: #008080;">then</span> <span style="color: #008080;">return</span> <span style="color: #7060A8;">mpz_init</span><span style="color: #0000FF;">({</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,-</span><span style="color: #000000;">2</span><span style="color: #0000FF;">,</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">1</span><span style="color: #0000FF;">}[</span><span style="color: #000000;">k</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;">if</span>
<span style="color: #004080;">mpz</span> <span style="color: #000000;">c0</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">mpz_init</span><span style="color: #0000FF;">(</span><span style="color: #000000;">3</span><span style="color: #0000FF;">),</span>
<span style="color: #000000;">c1</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">mpz_init</span><span style="color: #0000FF;">(</span><span style="color: #000000;">2</span><span style="color: #0000FF;">),</span>
<span style="color: #000000;">c2</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">mpz_init</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">),</span>
<span style="color: #000000;">c3</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">mpz_init</span><span style="color: #0000FF;">(</span><span style="color: #000000;">0</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">j</span><span style="color: #0000FF;">=</span><span style="color: #000000;">5</span> <span style="color: #008080;">to</span> <span style="color: #000000;">k</span><span style="color: #0000FF;">-</span><span style="color: #000000;">1</span> <span style="color: #008080;">do</span>
<span style="color: #7060A8;">mpz_add</span><span style="color: #0000FF;">(</span><span style="color: #000000;">c3</span><span style="color: #0000FF;">,</span><span style="color: #000000;">c3</span><span style="color: #0000FF;">,</span><span style="color: #000000;">c0</span><span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">mpz_sub_ui</span><span style="color: #0000FF;">(</span><span style="color: #000000;">c3</span><span style="color: #0000FF;">,</span><span style="color: #000000;">c3</span><span style="color: #0000FF;">,</span><span style="color: #000000;">1</span><span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">mpz_add</span><span style="color: #0000FF;">(</span><span style="color: #000000;">c0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">c0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">c1</span><span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">mpz_add</span><span style="color: #0000FF;">(</span><span style="color: #000000;">c1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">c1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">c2</span><span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">mpz_add</span><span style="color: #0000FF;">(</span><span style="color: #000000;">c2</span><span style="color: #0000FF;">,</span><span style="color: #000000;">c2</span><span style="color: #0000FF;">,</span><span style="color: #000000;">c3</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #7060A8;">mpz_sub</span><span style="color: #0000FF;">(</span><span style="color: #000000;">c0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">c0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">c1</span><span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">mpz_sub</span><span style="color: #0000FF;">(</span><span style="color: #000000;">c0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">c0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">c2</span><span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">mpz_add</span><span style="color: #0000FF;">(</span><span style="color: #000000;">c0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">c0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">c3</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">return</span> <span style="color: #000000;">c0</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #008080;">constant</span> <span style="color: #000000;">tests</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">tagset</span><span style="color: #0000FF;">(</span><span style="color: #000000;">20</span><span style="color: #0000FF;">,</span><span style="color: #000000;">0</span><span style="color: #0000FF;">)&{</span><span style="color: #000000;">30</span><span style="color: #0000FF;">,</span><span style="color: #000000;">39</span><span style="color: #0000FF;">,</span><span style="color: #000000;">500</span><span style="color: #0000FF;">,</span><span style="color: #000000;">10000</span><span style="color: #0000FF;">,</span><span style="color: #000000;">1e6</span><span style="color: #0000FF;">}</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">k</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">tests</span><span style="color: #0000FF;">)-(</span><span style="color: #7060A8;">platform</span><span style="color: #0000FF;">()=</span><span style="color: #004600;">JS</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
<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;">"A(%,d) = %s\n"</span><span style="color: #0000FF;">,</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">tests</span><span style="color: #0000FF;">[</span><span style="color: #000000;">k</span><span style="color: #0000FF;">],</span><span style="color: #7060A8;">mpz_get_short_str</span><span style="color: #0000FF;">(</span><span style="color: #000000;">A</span><span style="color: #0000FF;">(</span><span style="color: #000000;">tests</span><span style="color: #0000FF;">[</span><span style="color: #000000;">k</span><span style="color: #0000FF;">]))})</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<!--</syntaxhighlight>-->
{{out}}
<pre>
A(0) = 1
A(1) = 0
A(2) = -2
A(3) = 0
A(4) = 1
A(5) = 0
A(6) = 1
A(7) = -1
A(8) = -10
A(9) = -30
A(10) = -67
A(11) = -138
A(12) = -291
A(13) = -642
A(14) = -1446
A(15) = -3250
A(16) = -7244
A(17) = -16065
A(18) = -35601
A(19) = -78985
A(20) = -175416
A(30) = -512016658
A(39) = -672620048590
A(500) = -36608736847739011154...32375404781872267320 (172 digits)
A(10,000) = -19928164276191803466...30409380127296034899 (3,464 digits)
A(1,000,000) = -67341136870269950723...54621754484081195219 (346,497 digits)
</pre>
The 1e6 works fine under pwa/p2js but takes/causes a blank screen for 3 mins, compared to 45s for desktop/Phix, and 29s for the Go version.
 
=={{header|PHP}}==
{{works with|PHP|5.3+}}
<langsyntaxhighlight lang="php"><?php
function A($k,$x1,$x2,$x3,$x4,$x5) {
$b = function () use (&$b,&$k,$x1,$x2,$x3,$x4) {
Line 2,584 ⟶ 2,895:
function () { return 1; },
function () { return 0; }) . "\n";
?></langsyntaxhighlight>
 
{{works with|PHP|pre-5.3 and 5.3+}}
<langsyntaxhighlight lang="php"><?php
function A($k,$x1,$x2,$x3,$x4,$x5) {
static $i = 0;
Line 2,608 ⟶ 2,919:
create_function('', 'return 1;'),
create_function('', 'return 0;')) . "\n";
?></langsyntaxhighlight>
 
=={{header|PicoLisp}}==
As PicoLisp uses exclusively shallow dynamic binding, stack frames have to be
explicitly constructed.
<langsyntaxhighlight PicoLisplang="picolisp">(de a (K X1 X2 X3 X4 X5)
(let (@K (cons K) B (cons)) # Explicit frame
(set B
Line 2,620 ⟶ 2,931:
(if (gt0 (car @K)) ((car B)) (+ (X4) (X5))) ) )
 
(a 10 '(() 1) '(() -1) '(() -1) '(() 1) '(() 0))</langsyntaxhighlight>
Output:
<pre>-> -67</pre>
Line 2,677 ⟶ 2,988:
=={{header|Python}}==
{{works with|Python|2.5}}
<langsyntaxhighlight lang="python">#!/usr/bin/env python
import sys
sys.setrecursionlimit(1025)
Line 2,690 ⟶ 3,001:
x = lambda i: lambda: i
print(a(10, x(1), x(-1), x(-1), x(1), x(0)))
</syntaxhighlight>
</lang>
A better-looking alternative to using lists as storage are function attributes:
<langsyntaxhighlight lang="python">#!/usr/bin/env python
import sys
sys.setrecursionlimit(1025)
Line 2,705 ⟶ 3,016:
x = lambda i: lambda: i
print(a(10, x(1), x(-1), x(-1), x(1), x(0)))
</syntaxhighlight>
</lang>
 
Output:
Line 2,713 ⟶ 3,024:
{{works with|Python|3.0}}
 
<langsyntaxhighlight lang="python">#!/usr/bin/env python
import sys
sys.setrecursionlimit(1025)
Line 2,724 ⟶ 3,035:
return x4() + x5() if k <= 0 else B()
 
print(A(10, lambda: 1, lambda: -1, lambda: -1, lambda: 1, lambda: 0))</langsyntaxhighlight>
 
=={{header|R}}==
Like many implementations this uses lambda wrappers around the numeric arguments and explicit function calls in the x4() + x5() step to force the order of evaluation and handle value/call duality.
 
<langsyntaxhighlight Rlang="r">n <- function(x) function()x
 
A <- function(k, x1, x2, x3, x4, x5) {
Line 2,736 ⟶ 3,047:
}
 
A(10, n(1), n(-1), n(-1), n(1), n(0))</langsyntaxhighlight>
 
That is the way any sane person would implement Man-or-Boy. However, we can be a bit more evil than that. Here <tt>call.by.name</tt> is a function that rewrites the function definition given as its input:
 
<langsyntaxhighlight lang="r">call.by.name <- function(...) {
cl <- as.list(match.call())
sublist <- lapply(cl[2:(length(cl)-1)],
Line 2,754 ⟶ 3,065:
}, list(body=fndef[[3]], subcall=subcall))
eval.parent(fndef)
}</langsyntaxhighlight>
 
allowing us to write A in a way that mirrors ALGOL60 semantics closely:
 
<langsyntaxhighlight Rlang="r">A <- call.by.name(x1, x2, x3, x4, x5,
function(k, x1, x2, x3, x4, x5) {
Aout <- NULL
Line 2,768 ⟶ 3,079:
Aout
}
)</langsyntaxhighlight>
 
One has to increase the recursion limit a bit, but it gives correct answers:
 
<langsyntaxhighlight lang="r">> options(expressions=10000)
> mapply(A, 0:10, 1, -1, -1, 1, 0)
[1] 1 0 -2 0 1 0 1 -1 -10 -30 -67</langsyntaxhighlight>
If you inspect <tt>A</tt> without the original source you will see what has happened: <tt>call.by.name</tt> rewrote A so that it looks like this:
 
<langsyntaxhighlight lang="r">> print(A, useSource=FALSE)
function (k, x1, x2, x3, x4, x5)
{
Line 2,795 ⟶ 3,106:
x4 = substitute(evalq(., .caller), list(. = substitute(x4))),
x5 = substitute(evalq(., .caller), list(. = substitute(x5))))))
}</langsyntaxhighlight>
 
That is, instead of evaluating its arguments normally, <tt>A</tt> captures their original expressions, and instead of evaluating its body normally, <tt>A</tt> substitutes calls to <tt>evalq</tt> the captured argument expressions in the calling frame. After a few levels of recursion this way, you end up evaluating expressions like <tt>A(k, B(), evalq(B(), .caller), evalq(evalq(B(), .caller), .caller), evalq(evalq(evalq(1, .caller), .caller), .caller), evalq(evalq(evalq(-1, .caller), .caller), .caller))</tt>, so this is not very efficient, but works.
Line 2,803 ⟶ 3,114:
Copied from Scheme, works fine:
 
<langsyntaxhighlight Racketlang="racket">#lang racket
 
(define (A k x1 x2 x3 x4 x5)
Line 2,813 ⟶ 3,124:
(B)))
(A 10 (lambda () 1) (lambda () -1) (lambda () -1) (lambda () 1) (lambda () 0))</langsyntaxhighlight>
 
Use "named let" to define and implicitly execute B:
 
<syntaxhighlight lang="racket">#lang racket
 
(define (A k x1 x2 x3 x4 x5)
(if (<= k 0)
(+ (x4) (x5))
(let B ()
(set! k (- k 1))
(A k B x1 x2 x3 x4))))
(A 10 (lambda () 1) (lambda () -1) (lambda () -1) (lambda () 1) (lambda () 0))</syntaxhighlight>
 
=={{header|Raku}}==
(formerly Perl 6)
This solution avoids creating the closure B if $k <= 0 (that is, nearly every time).
<syntaxhighlight lang="raku" line>sub A($k is copy, &x1, &x2, &x3, &x4, &x5) {
$k <= 0
?? x4() + x5()
!! (my &B = { A(--$k, &B, &x1, &x2, &x3, &x4) })();
};
say A(10, {1}, {-1}, {-1}, {1}, {0});</syntaxhighlight>
{{out}}
<pre>-67</pre>
 
=={{header|REXX}}==
The REXX language only passes by value, not by name. &nbsp; However, there is a way to treat passed arguments as names.
<br>However, using the code below, it only works for &nbsp; '''n''' &nbsp; up to (and including) &nbsp; '''3'''.
<langsyntaxhighlight lang="rexx">/*REXX program performs the "man or boy" test as far as possible for N. */
do n=0 /*increment N from zero forever. */
say 'n='n a(N,x1,x2,x3,x4,x5) /*display the result to the terminal. */
Line 2,834 ⟶ 3,171:
x3: procedure; return -1
x4: procedure; return 1
x5: procedure; return 0</langsyntaxhighlight>
'''output'''
<pre>
Line 2,846 ⟶ 3,183:
 
Note: the lambda call can be replaced with Proc.new and still work.
<langsyntaxhighlight lang="ruby">def a(k, x1, x2, x3, x4, x5)
b = lambda { k -= 1; a(k, b, x1, x2, x3, x4) }
k <= 0 ? x4[] + x5[] : b[]
end
 
puts a(10, lambda {1}, lambda {-1}, lambda {-1}, lambda {1}, lambda {0})</langsyntaxhighlight>
 
 
=={{header|Rust}}==
 
<langsyntaxhighlight lang="rust">use std::cell::Cell;
 
trait Arg {
Line 2,894 ⟶ 3,230:
pub fn main() {
println!("{}", a(10, &1, &-1, &-1, &1, &0));
}</langsyntaxhighlight>
 
Another solution where we have B take itself as an argument in order to recursively call itself:
 
<langsyntaxhighlight lang="rust">use std::cell::Cell;
 
fn a(k: i32, x1: &Fn() -> i32, x2: &Fn() -> i32, x3: &Fn() -> i32, x4: &Fn() -> i32, x5: &Fn() -> i32) -> i32 {
Line 2,910 ⟶ 3,246:
};
let b = ||(b.f)(&b);
return if k <= 0 {x4() + x5()} else {b()}
return x4() + x5()
} else {
return b()
}
}
 
pub fn main() {
println!("{}", a(10, &||1, &||-1, &||-1, &||1, &||0));
}</langsyntaxhighlight>
 
Another solution that gives a reference-counted function a weak reference to itself:
 
{{trans|Objective-C}}
<lang rust>use std::cell::Cell;
<syntaxhighlight lang="rust">use std::cell::Cell;
use std::cell::RefCell;
use std::rc::Rc;
Line 2,931 ⟶ 3,264:
let weak_holder: Rc<RefCell<Weak<Fn() -> i32>>> = Rc::new(RefCell::new(Weak::<fn() -> i32>::new()));
let weak_holder2 = weak_holder.clone();
let k1k_holder = Cell::new(k);
let b: Rc<Fn() -> i32> = Rc::new(move || {
let b = weak_holder2.borrow().upgrade().unwrap();
k1k_holder.set(k1k_holder.get() - 1);
return a(k1k_holder.get(), &*b, x1, x2, x3, x4);
});
weak_holder.replace(Rc::downgrade(&b));
 
return if k <= 0 {x4() + x5()} else {b()}
return x4() + x5()
} else {
return b()
}
}
 
pub fn main() {
println!("{}", a(10, &||1, &||-1, &||-1, &||1, &||0));
}</langsyntaxhighlight>
 
=={{header|Scala}}==
<langsyntaxhighlight lang="scala">def A(in_k: Int, x1: =>Int, x2: =>Int, x3: =>Int, x4: =>Int, x5: =>Int): Int = {
var k = in_k
def B: Int = {
Line 2,959 ⟶ 3,288:
if (k<=0) x4+x5 else B
}
println(A(10, 1, -1, -1, 1, 0))</langsyntaxhighlight>
 
=={{header|Scheme}}==
 
<syntaxhighlight lang="scheme">(define (A k x1 x2 x3 x4 x5)
(define (B)
(set! k (- k 1))
(A k B x1 x2 x3 x4))
(if (<= k 0)
(+ (x4) (x5))
(B)))
 
(A 10 (lambda () 1) (lambda () -1) (lambda () -1) (lambda () 1) (lambda () 0))</syntaxhighlight>
 
=={{header|Sidef}}==
<langsyntaxhighlight lang="ruby">func a(k, x1, x2, x3, x4, x5) {
func b { a(--k, b, x1, x2, x3, x4) };
k <= 0 ? (x4() + x5()) : b();
}
say a(10, ->{1}, ->{-1}, ->{-1}, ->{1}, ->{0}); #=> -67</langsyntaxhighlight>
 
This solution avoids creating the closure b if k <= 0 (that is, nearly every time).
<langsyntaxhighlight lang="ruby">func a(k, x1, x2, x3, x4, x5) {
k <= 0 ? (x4() + x5())
: func b { a(--k, b, x1, x2, x3, x4) }();
}
say a(10, ->{1}, ->{-1}, ->{-1}, ->{1}, ->{0}); #=> -67</langsyntaxhighlight>
 
Alternatively, we can implement it as a class also:
<langsyntaxhighlight lang="ruby">class MOB {
method a(k, x1, x2, x3, x4, x5) {
func b { self.a(--k, b, x1, x2, x3, x4) };
Line 2,984 ⟶ 3,325:
 
var obj = MOB();
say obj.a(10, ->{1}, ->{-1}, ->{-1}, ->{1}, ->{0});</langsyntaxhighlight>
 
=={{header|Snap!Smalltalk}}==
 
[[File:snap-man-or-boy.png]]
 
=={{header|Scheme}}==
 
<lang scheme>(define (A k x1 x2 x3 x4 x5)
(define (B)
(set! k (- k 1))
(A k B x1 x2 x3 x4))
(if (<= k 0)
(+ (x4) (x5))
(B)))
 
(A 10 (lambda () 1) (lambda () -1) (lambda () -1) (lambda () 1) (lambda () 0))</lang>
 
=={{header|Smalltalk}} ==
 
Number>>x1: x1 x2: x2 x3: x3 x4: x4 x5: x5
Line 3,011 ⟶ 3,336:
10 x1: [1] x2: [-1] x3: [-1] x4: [1] x5: [0]
 
=={{header|Snap!}}==
 
[[File:snap-man-or-boy.png]]
 
=={{header|Sparkling}}==
Sparkling does not directly support modifying external local variables. To work around this limitation, we wrap the <tt>k</tt> variable in an array, which is mutable.
 
<langsyntaxhighlight lang="sparkling">function a(k, x1, x2, x3, x4, x5) {
let kk = { "k": k.k };
let b = function b() {
Line 3,030 ⟶ 3,359:
}
 
print(a({ "k": 10 }, x(1), x(-1), x(-1), x(1), x(0)));</langsyntaxhighlight>
 
=={{header|Standard ML}}==
Line 3,036 ⟶ 3,365:
Standard ML variables are not mutable, so "k" is wrapped in a mutable object, which we access through a reference type called "ref".
 
<langsyntaxhighlight lang="sml">fun a (k, x1, x2, x3, x4, x5) =
if k <= 0 then
x4 () + x5 ()
Line 3,050 ⟶ 3,379:
 
val () =
print (Int.toString (a (10, fn () => 1, fn () => ~1, fn () => ~1, fn () => 1, fn () => 0)) ^ "\n")</langsyntaxhighlight>
 
=={{header|Swift}}==
Line 3,057 ⟶ 3,386:
As of Swift 3.0, closure parameters are "non-escaping" by default. The Man or Boy Test requires the closures to be escaping, and thus we must now annotate the closure parameters with the "@escaping" attribute.
 
<langsyntaxhighlight lang="swift">func A(_ k: Int,
_ x1: @escaping () -> Int,
_ x2: @escaping () -> Int,
Line 3,077 ⟶ 3,406:
}
print(A(10, {1}, {-1}, {-1}, {1}, {0}))</langsyntaxhighlight>
{{works with|Swift|2.x}}
<langsyntaxhighlight lang="swift">func A(k: Int, _ x1: () -> Int, _ x2: () -> Int, _ x3: () -> Int, _ x4: () -> Int, _ x5: () -> Int) -> Int {
var k1 = k
func B() -> Int {
Line 3,092 ⟶ 3,421:
}
 
print(A(10, {1}, {-1}, {-1}, {1}, {0}))</langsyntaxhighlight>
{{works with|Swift|1.x}}
<langsyntaxhighlight lang="swift">func A(var k: Int, x1: () -> Int, x2: () -> Int, x3: () -> Int, x4: () -> Int, x5: () -> Int) -> Int {
var B: (() -> Int)!
B = {
Line 3,107 ⟶ 3,436:
}
 
println(A(10, {1}, {-1}, {-1}, {1}, {0}))</langsyntaxhighlight>
 
=={{header|Tcl}} ==
 
There are two nontrivial features in the "man or boy" test. One is that the parameters ''x1'' though ''x5'' are in general going to be function calls that don't get evaluated until their values are needed for the addition in procedure A, which means that these in Tcl are going to be scripts, and therefore it is necessary to introduce a helper procedure C that returns a constant value. The other is that procedure B needs to refer to variables in the local context of its "parent" instance of procedure A. This is precisely what the '''upvar''' core command does, but the ''absolute'' target level needs to be embedded into the script that performs the delayed call to procedure B ('''upvar''' is more often used with relative levels).
<langsyntaxhighlight lang="tcl">proc A {k x1 x2 x3 x4 x5} {
expr {$k<=0 ? [eval $x4]+[eval $x5] : [B \#[info level]]}
}
Line 3,122 ⟶ 3,451:
proc C {val} {return $val}
interp recursionlimit {} 1157
A 10 {C 1} {C -1} {C -1} {C 1} {C 0}</langsyntaxhighlight>
 
The <tt>[info level 0]</tt> here is a sort of "self" idiom; it returns the command (with arguments) that called the current procedure.
 
Since the values of ''x1'' through ''x4'' are never modified, it is also possible to embed these as parameters of B, thereby slightly purifying the program:
<langsyntaxhighlight lang="tcl">proc AP {k x1 x2 x3 x4 x5} {expr {$k<=0 ? [eval $x4]+[eval $x5] : [BP \#[info level] $x1 $x2 $x3 $x4]}}
proc BP {level x1 x2 x3 x4} {AP [uplevel $level {incr k -1}] [info level 0] $x1 $x2 $x3 $x4}
proc C {val} {return $val}
interp recursionlimit {} 1157
AP 10 {C 1} {C -1} {C -1} {C 1} {C 0}</langsyntaxhighlight>
 
=={{header|TSQL}}==
 
SQL is kinda limited, and TSQL is not much better. Unfortunately it fails the Man test due to Stack Level being limited to 32.
<langsyntaxhighlight lang="tsql">
CREATE PROCEDURE dbo.LAMBDA_WRAP_INTEGER
 
Line 3,280 ⟶ 3,609:
END
 
</syntaxhighlight>
</lang>
 
Outputs:
Line 3,287 ⟶ 3,616:
For k=3, result=0
For k=4, result=1
 
 
=={{header|TXR}}==
Line 3,293 ⟶ 3,621:
The goal in this solution is to emulate the Algol 60 solution as closely as possible, and not merely get the correct result. For that, we could just crib the Common Lisp or Scheme solution, with more succinct syntax, like this:
 
<langsyntaxhighlight lang="txrlisp">(defun A (k x1 x2 x3 x4 x5)
(labels ((B ()
(dec k)
Line 3,299 ⟶ 3,627:
(if (<= k 0) (+ [x4] [x5]) (B))))
 
(prinl (A 10 (ret 1) (ret -1) (ret -1) (ret 1) (ret 0)))</langsyntaxhighlight>
 
To do a proper job, we define a call-by-name system as a set of functions and macros. With these, the function <code>A</code> can be defined as a close transliteration of the Algol, as can the call to <code>A</code> with the integer constants:
 
<langsyntaxhighlight lang="txrlisp">(defun-cbn A (k x1 x2 x3 x4 x5)
(let ((k k))
(labels-cbn (B ()
Line 3,312 ⟶ 3,640:
(B))))) ;; value of (B) correctly discarded here!
 
(prinl (A 10 1 -1 -1 1 0))</langsyntaxhighlight>
 
We define the global function with <code>defun-cbn</code> ("cbn" stands for "call by name") and the inner function with <code>labels-cbn</code>. These functions are actually macros which call hidden call-by-value functions. The macros create all the necessary thunks out of their argument expressions, and the hidden functions use local macros to provide transparent access to their arguments from their bodies.
Line 3,324 ⟶ 3,652:
The complete code follows:
 
<langsyntaxhighlight lang="txrlisp">(defstruct (cbn-thunk get set) nil get set)
 
(defmacro make-cbn-val (place)
Line 3,391 ⟶ 3,719:
(B))))) ;; value of (B) correctly discarded here!
 
(prinl (A 10 1 -1 -1 1 0))</langsyntaxhighlight>
 
=={{header|Visual Prolog}} ==
 
Visual Prolog (like any other Prolog) does not allow variables to be changed. But behavior can easily be mimicked by using a '''varM''' (modifiable variable), which is actually an object containing a value of the relevant type in a modifiable entity (a so called fact variable). Secondly, anonymous function (lambda-expression) cannot be recursive, but this is mimicked by using yet a '''varM''' to hold the function.
Line 3,399 ⟶ 3,727:
(Token coloring of Visual Prolog in this wiki is unfortunately wrong, because styles are used across languages. A correctly colored version can be seen in [http://wiki.visual-prolog.com/index.php?title=Man_or_boy_test Man or boy test] in the Visual Prolog wiki).
 
<syntaxhighlight lang="visualprolog">
<lang VisualProlog>
implement main
open core
Line 3,421 ⟶ 3,749:
R = if KM:value <= 0 then X4() + X5() else BM:value() end if.
 
end implement main</langsyntaxhighlight>
 
=={{header|Vorpal}} ==
Adapted from the Lua example. In vorpal, all execution is a message to an object. This task primarily involves functions, so we have the apply the function objects to self for them to execute. Correctly, prints -67.
 
<langsyntaxhighlight lang="vorpal">self.a = method(k, x1, x2, x3, x4, x5){
b = method(){
code.k = code.k - 1
Line 3,454 ⟶ 3,782:
}
 
self.a(10, self.K(1), self.K(-1), self.K(-1), self.K(1), self.K(0)).print()</langsyntaxhighlight>
 
=={{header|Wren}}==
===CLI===
In Wren, a fiber's stack starts quite small but is then increased as needed, apparently limited only by available memory. Anyway, satisfying the test for k up to 20 is unlikely to be a problem on a modern machine.
<syntaxhighlight lang="wren">import "./fmt" for Fmt
 
var a
a = Fn.new { |k, x1, x2, x3, x4, x5|
var b
b = Fn.new {
k = k - 1
return a.call(k, b, x1, x2, x3, x4)
}
return (k <= 0) ? x4.call() + x5.call() : b.call()
}
 
System.print(" k a")
for (k in 0..20) {
Fmt.print("$2d : $ d", k, a.call(k, Fn.new { 1 }, Fn.new { -1 }, Fn.new { -1 }, Fn.new { 1 }, Fn.new { 0 }))
}</syntaxhighlight>
 
{{out}}
<pre>
k a
0 : 1
1 : 0
2 : -2
3 : 0
4 : 1
5 : 0
6 : 1
7 : -1
8 : -10
9 : -30
10 : -67
11 : -138
12 : -291
13 : -642
14 : -1446
15 : -3250
16 : -7244
17 : -16065
18 : -35601
19 : -78985
20 : -175416
</pre>
===Embedded (GMP)===
{{libheader|Wren-gmp}}
{{libheader|Wren-fmt}}
Based on Go's 'faster' version this runs in about 15.2 seconds which (surprisingly) is slightly faster than Go itself (16.6 seconds).
<syntaxhighlight lang="wren">/* Man_or_boy_test_2.wren */
 
import "./gmp" for Mpz
import "./fmt" for Fmt
 
var A = Fn.new { |k|
if (k < 6) {
var x1 = 1
var x2 = -1
var x3 = -1
var x4 = 1
var c1 = [0, 0, 0, 1, 2, 3][k]
var c2 = [0, 0, 1, 1, 1, 2][k]
var c3 = [0, 1, 1, 0, 0, 1][k]
var c4 = [1, 1, 0, 0, 0, 0][k]
return c1*x1 + c2*x2 + c3*x3 + c4*x4
}
var one = Mpz.one
var c0 = Mpz.three
var c1 = Mpz.two
var c2 = Mpz.one
var c3 = Mpz.zero
for (j in 5...k) {
c3.add(c0).sub(one)
c0.add(c1)
c1.add(c2)
c2.add(c3)
}
return c0.add(c0.sub(c0.sub(c1), c2), c3)
}
 
var p = Fn.new { |k|
Fmt.write("A($d) = ", k)
var s = A.call(k).toString
if (s.count < 60) {
System.print(s)
} else {
Fmt.print("$s...$s ($d digits)", s[0..5], s[-5..-1], s.count - 1)
}
}
 
for (i in 0..39) p.call(i)
p.call(500)
p.call(10000)
p.call(1e6) </syntaxhighlight>
 
{{out}}
<pre>
Same as Go 'faster' version.
</pre>
 
=={{header|Zig}}==
'''Works with:''' 0.10.x, 0.11.x, 0.12.0-dev.1390+94cee4fb2
 
<syntaxhighlight lang="zig">const Record = struct {
yieldFn: *const fn (record: *Record) i32,
 
k: *i32 = undefined,
x1: *Record = undefined,
x2: *Record = undefined,
x3: *Record = undefined,
x4: *Record = undefined,
x5: *Record = undefined,
 
inline fn run(record: *Record) i32 {
return record.yieldFn(record);
}
 
pub fn A(record: *Record) i32 {
return if (record.k.* <= 0)
record.x4.run() + record.x5.run()
else
record.B();
}
 
fn B(record: *Record) i32 {
record.k.* -= 1;
 
var k_copy_on_stack: i32 = record.k.*;
 
var b: Record = .{
.yieldFn = &Record.B,
 
.k = &k_copy_on_stack,
.x1 = record,
.x2 = record.x1,
.x3 = record.x2,
.x4 = record.x3,
.x5 = record.x4,
};
return b.A();
}
};
 
const numbers = struct {
fn positiveOne(unused_record: *Record) i32 {
_ = unused_record;
return 1;
}
 
fn zero(unused_record: *Record) i32 {
_ = unused_record;
return 0;
}
 
fn negativeOne(unused_record: *Record) i32 {
_ = unused_record;
return -1;
}
};
 
const std = @import("std");
 
pub fn main() void {
var i: u31 = 0;
while (i <= 31) : (i += 1) {
var k: i32 = i;
var @"+1_record": Record = .{ .yieldFn = &numbers.positiveOne };
var @"0_record": Record = .{ .yieldFn = &numbers.zero };
var @"-1_record": Record = .{ .yieldFn = &numbers.negativeOne };
 
var record: Record = .{
.yieldFn = &Record.B,
 
.k = &k,
.x1 = &@"+1_record",
.x2 = &@"-1_record",
.x3 = &@"-1_record",
.x4 = &@"+1_record",
.x5 = &@"0_record",
};
 
std.debug.print("[{d:>3}] = {d}\n", .{ i, record.A() });
}
}</syntaxhighlight>
 
{{out}}
<pre>
$ zig build-exe -OReleaseSmall -fstrip src/man_or_boy_test.zig
$ ulimit -s
8192
 
$ ./man_or_boy_test
[ 0] = 1
[ 1] = 0
[ 2] = -2
[ 3] = 0
[ 4] = 1
[ 5] = 0
[ 6] = 1
[ 7] = -1
[ 8] = -10
[ 9] = -30
[ 10] = -67
[ 11] = -138
[ 12] = -291
[ 13] = -642
[ 14] = -1446
[ 15] = -3250
[ 16] = -7244
[ 17] = -16065
[ 18] = -35601
[1] 22315 segmentation fault ./man_or_boy_test
 
$ ulimit -s 71296
$ ./man_or_boy_test
[ 0] = 1
[ 1] = 0
[ 2] = -2
[ 3] = 0
[ 4] = 1
[ 5] = 0
[ 6] = 1
[ 7] = -1
[ 8] = -10
[ 9] = -30
[ 10] = -67
[ 11] = -138
[ 12] = -291
[ 13] = -642
[ 14] = -1446
[ 15] = -3250
[ 16] = -7244
[ 17] = -16065
[ 18] = -35601
[ 19] = -78985
[ 20] = -175416
[1] 22384 segmentation fault ./man_or_boy_test
</pre>
 
=={{header|zkl}} ==
The compiler is OK but the VM is a girlie-man VM. Due to the way closures are built, the stack blows quickly when closures recurse. So, while the code can be written per Knuth, it is unable to do anything. So, classes are used to simulate the closures. Also (5)()-->5 so no problems there.
<langsyntaxhighlight lang="zkl">fcn A(k, x1, x2, x3, x4, x5){ // -->1,0,-2,0,1,0,1,-1,-10,-30,-67,-138
B:=CB(k, x1, x2, x3, x4, x5);
if(k <= 0) x4()+x5() else B.B();
Line 3,473 ⟶ 4,040:
A(k, B, x1, x2, x3, x4);
}
}</langsyntaxhighlight>
{{out}}
<pre>
Anonymous user