Man or boy test: Difference between revisions

→‎F#: Add CPS version of straightforward approach.
imported>GLChapman
(→‎F#: Add CPS version of straightforward approach.)
 
(18 intermediate revisions by 9 users not shown)
Line 233:
{{works with|Ada|Ada|2005, 2012}}
 
<langsyntaxhighlight lang="ada">with Ada.Text_IO; use Ada.Text_IO;
 
procedure Man_Or_Boy is
Line 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 274:
{{works with|Ada|Ada|2012}}
 
<langsyntaxhighlight lang="ada">with Ada.Text_IO; use Ada.Text_IO;
 
procedure Man_Or_Boy is
Line 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 347:
X5 => Zero'Access)));
 
end Man_Or_Boy;</langsyntaxhighlight>
 
Sample output:
Line 355:
 
=={{header|Aime}}==
<langsyntaxhighlight lang="aime">integer
F(list l)
{
Line 406:
 
0;
}</langsyntaxhighlight>
Output:
<pre>
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>
Line 471:
<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.
<langsyntaxhighlight lang="algolw">begin
real procedure A (integer value k; real procedure x1, x2, x3, x4, x5);
begin
Line 481:
end;
write (r_format := "A", r_w := 8, r_d := 2, A (10, 1, -1, -1, 1, 0))
end.</langsyntaxhighlight>
{{out}}
<pre>
Line 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 512:
 
a(10, int(1), int(-1), int(-1), int(1), int(0))
</syntaxhighlight>
</lang>
Output:
<pre>
Line 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 544 ⟶ 545:
DEF FN0(d%) = 0
DEF FN1(d%) = 1
DEF FN_1(d%) = -1</langsyntaxhighlight>
Output:
<pre>
Line 574 ⟶ 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 616 ⟶ 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 631 ⟶ 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 681 ⟶ 682:
printf("%d\n", A(Frame(&a, &k, &f1, &fn1, &fn1, &f1, &f0)));
return 0;
}</langsyntaxhighlight>
 
Output:
Line 691 ⟶ 692:
{{works with|C sharp|C#|2+}}
 
<langsyntaxhighlight lang="csharp">using System;
delegate T Func<T>();
Line 714 ⟶ 715:
}
}
</syntaxhighlight>
</lang>
 
C# 3.0 supports lambda expressions which are used in the implementation below:
Line 720 ⟶ 721:
{{works with|C sharp|C#|3+}}
 
<langsyntaxhighlight lang="csharp">using System;
class ManOrBoy
Line 735 ⟶ 736:
return k <= 0 ? x4() + x5() : b();
}
}</langsyntaxhighlight>
 
=={{header|C++}}==
Line 742 ⟶ 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 794 ⟶ 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 821 ⟶ 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 855 ⟶ 856:
std::cout << A(10, L(1), L(-1), L(-1), L(1), L(0)) << std::endl;
return 0;
}</langsyntaxhighlight>
 
=={{header|Clipper}}==
 
<langsyntaxhighlight Clipperlang="clipper">Procedure Main()
Local k
For k := 0 to 20
Line 883 ⟶ 884:
xVal := x
Endif
Return xVal</langsyntaxhighlight>
 
 
Line 917 ⟶ 918:
=={{header|Clojure}}==
 
<langsyntaxhighlight lang="lisp">(declare a)
 
(defn man-or-boy
Line 941 ⟶ 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 960 ⟶ 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 969 ⟶ 970:
end
 
puts a(10, -> {1}, -> {-1}, -> {-1}, -> {1}, -> {0})</langsyntaxhighlight>
{{out}}
<pre>
Line 977 ⟶ 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 990 ⟶ 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 996 ⟶ 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 1,009 ⟶ 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,039 ⟶ 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,082 ⟶ 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,142 ⟶ 1,143:
writefln("...\n500 %-(%s\\\n %)",
A(500, 1, -1, -1, 1, 0).text.chunks(60));
}</langsyntaxhighlight>
{{out}}
<pre>0 1
Line 1,193 ⟶ 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,221 ⟶ 1,222:
begin
Writeln(A(10, C(1), C(-1), C(-1), C(1), C(0))); // -67 output
end.</langsyntaxhighlight>
 
=={{header|Dyalect}}==
 
<langsyntaxhighlight Dyalectlang="dyalect">func _C(i) {
() => i
}
Line 1,242 ⟶ 1,243:
}
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,275 ⟶ 1,298:
end method man-or-boy;
 
format-out("%d\n", man-or-boy(10))</langsyntaxhighlight>
 
=={{header|Déjà Vu}}==
Line 1,281 ⟶ 1,304:
{{trans|Python}}
 
<langsyntaxhighlight lang="dejavu">a k x1 x2 x3 x4 x5:
local b:
set :k -- k
Line 1,293 ⟶ 1,316:
i
 
!. a 10 x 1 x -1 x -1 x 1 x 0</langsyntaxhighlight>
 
=={{header|E}}==
Line 1,299 ⟶ 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,313 ⟶ 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,335 ⟶ 1,358:
❗ InternalError : too much recursion - JS internal error (please, report it)-
→ stack overflow using FireFox
</syntaxhighlight>
</lang>
 
=={{header|Ela}}==
Line 1,341 ⟶ 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,355 ⟶ 1,378:
 
_ = a 10 (!!1) (!! -1) (!! -1) (!!1) (!!0) >>= (putStr << show) ::: IO
where (!!) f = & return f ::: IO</langsyntaxhighlight>
 
=={{header|Elena}}==
ELENA 46.1x:
<langsyntaxhighlight lang="elena">import extensions;
 
A(k,x1,x2,x3,x4,x5)
Line 1,379 ⟶ 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,438 ⟶ 1,461:
▶ 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,471 ⟶ 1,523:
Straightforward version:
 
<langsyntaxhighlight lang="fsharp">
[<EntryPoint>]
let main (args : string[]) =
Line 1,492 ⟶ 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,552 ⟶ 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,572 ⟶ 1,648:
}
}
</syntaxhighlight>
</lang>
 
yields
Line 1,584 ⟶ 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,590 ⟶ 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,649 ⟶ 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,670 ⟶ 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,697 ⟶ 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,733 ⟶ 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,744 ⟶ 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,769 ⟶ 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,790 ⟶ 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,799 ⟶ 1,923:
return k<=0 ? x4()+x5() : B()
}
print(A(10, \ -> 1, \ -> -1, \ -> -1, \ -> 1, \ -> 0))</langsyntaxhighlight>
 
Output:
Line 1,808 ⟶ 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,815 ⟶ 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,826 ⟶ 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,859 ⟶ 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 Data.IORef (modifyIORef, newIORef, readIORef)
 
a
Line 1,878 ⟶ 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,924 ⟶ 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,946 ⟶ 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,959 ⟶ 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>
 
=={{header|Io}}==
Line 1,965 ⟶ 2,089:
Io is nothing if not aggressively manly.
 
<langsyntaxhighlight lang="io">Range
 
a := method(k, xs,
Line 1,978 ⟶ 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,984 ⟶ 2,108:
Given
 
<langsyntaxhighlight Jlang="j">A=:4 :0
L=.cocreate'' NB. L is context where names are defined.
k__L=:x
Line 1,996 ⟶ 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 2,008 ⟶ 2,132:
Java Version 8 and up
 
<langsyntaxhighlight lang="java">import java.util.function.DoubleSupplier;
 
public class ManOrBoy {
Line 2,028 ⟶ 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,058 ⟶ 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,076 ⟶ 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 = () => 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,113 ⟶ 2,237:
-67
=!EXPECTEND!=
*/</langsyntaxhighlight>
 
{{out}}
Line 2,122 ⟶ 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,147 ⟶ 2,271:
}
}
</syntaxhighlight>
</lang>
 
{{out}}
Line 2,168 ⟶ 2,292:
 
=={{header|Lox}}==
<langsyntaxhighlight lang="lox">fun A (k, xa, xb, xc, xd, xe) {
print k;
fun B() {
Line 2,185 ⟶ 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,203 ⟶ 2,327:
end
print(a(10, K(1), K(-1), K(-1), K(1), K(0)))</langsyntaxhighlight>
 
=={{header|Mathematica}}/{{header|Wolfram Language}}==
This ''Mathematica'' code was derived from the Ruby example appearing below.
<langsyntaxhighlight Mathematicalang="mathematica">$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 &]</langsyntaxhighlight>
{{out}}
<pre>-67</pre>
Line 2,218 ⟶ 2,342:
=={{header|Modula-3}}==
 
<langsyntaxhighlight lang="modula3">MODULE Main;
IMPORT IO;
 
Line 2,246 ⟶ 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.
<langsyntaxhighlight lang="nim">import sugar
 
proc a(k: int; x1, x2, x3, x4, x5: proc(): int): int =
Line 2,260 ⟶ 2,384:
else: b()
 
echo a(10, () => 1, () => -1, () => -1, () => 1, () => 0)</langsyntaxhighlight>
 
{{out}}
Line 2,267 ⟶ 2,391:
=={{header|Objeck}}==
Using anonymous classes instead of closures
<langsyntaxhighlight lang="objeck">interface Arg {
method : virtual : public : Run() ~ Int;
}
Line 2,311 ⟶ 2,435:
}
}
</syntaxhighlight>
</lang>
 
=={{header|Objective-C}}==
{{works with|Cocoa|Mac OS X 10.6+}}
<langsyntaxhighlight lang="objc">#import <Foundation/Foundation.h>
 
typedef NSInteger (^IntegerBlock)(void);
Line 2,339 ⟶ 2,463:
}
return 0;
}</langsyntaxhighlight>
 
Without ARC, the above should be:
<langsyntaxhighlight lang="objc">#import <Foundation/Foundation.h>
 
typedef NSInteger (^IntegerBlock)(void);
Line 2,365 ⟶ 2,489:
[pool drain];
return 0;
}</langsyntaxhighlight>
 
 
without Blocks or ARC:
<langsyntaxhighlight lang="objc">@protocol IntegerFun <NSObject>
-(NSInteger)call;
@end
Line 2,441 ⟶ 2,565:
[pool release];
return 0;
}</langsyntaxhighlight>
 
=={{header|OCaml}}==
Line 2,447 ⟶ 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,459 ⟶ 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,466 ⟶ 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,494 ⟶ 2,655:
(print (man-or-boy 15))
(print (man-or-boy 20))
</syntaxhighlight>
</lang>
Output:
<pre>
Line 2,509 ⟶ 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,529 ⟶ 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,557 ⟶ 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,567 ⟶ 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,577 ⟶ 2,738:
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,629 ⟶ 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,653 ⟶ 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,665 ⟶ 2,931:
(if (gt0 (car @K)) ((car B)) (+ (X4) (X5))) ) )
 
(a 10 '(() 1) '(() -1) '(() -1) '(() 1) '(() 0))</langsyntaxhighlight>
Output:
<pre>-> -67</pre>
Line 2,722 ⟶ 2,988:
=={{header|Python}}==
{{works with|Python|2.5}}
<langsyntaxhighlight lang="python">#!/usr/bin/env python
import sys
sys.setrecursionlimit(1025)
Line 2,735 ⟶ 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,750 ⟶ 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,758 ⟶ 3,024:
{{works with|Python|3.0}}
 
<langsyntaxhighlight lang="python">#!/usr/bin/env python
import sys
sys.setrecursionlimit(1025)
Line 2,769 ⟶ 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,781 ⟶ 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,799 ⟶ 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,813 ⟶ 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,840 ⟶ 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,848 ⟶ 3,114:
Copied from Scheme, works fine:
 
<langsyntaxhighlight Racketlang="racket">#lang racket
 
(define (A k x1 x2 x3 x4 x5)
Line 2,858 ⟶ 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" perl6line>sub A($k is copy, &x1, &x2, &x3, &x4, &x5) {
$k <= 0
?? x4() + x5()
Line 2,869 ⟶ 3,148:
};
say A(10, {1}, {-1}, {-1}, {1}, {0});</langsyntaxhighlight>
{{out}}
<pre>-67</pre>
Line 2,876 ⟶ 3,155:
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,892 ⟶ 3,171:
x3: procedure; return -1
x4: procedure; return 1
x5: procedure; return 0</langsyntaxhighlight>
'''output'''
<pre>
Line 2,904 ⟶ 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,951 ⟶ 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,972 ⟶ 3,251:
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}}
<langsyntaxhighlight lang="rust">use std::cell::Cell;
use std::cell::RefCell;
use std::rc::Rc;
Line 2,998 ⟶ 3,277:
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 3,009 ⟶ 3,288:
if (k<=0) x4+x5 else B
}
println(A(10, 1, -1, -1, 1, 0))</langsyntaxhighlight>
 
=={{header|Scheme}}==
 
<langsyntaxhighlight lang="scheme">(define (A k x1 x2 x3 x4 x5)
(define (B)
(set! k (- k 1))
Line 3,021 ⟶ 3,300:
(B)))
 
(A 10 (lambda () 1) (lambda () -1) (lambda () -1) (lambda () 1) (lambda () 0))</langsyntaxhighlight>
 
=={{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 3,046 ⟶ 3,325:
 
var obj = MOB();
say obj.a(10, ->{1}, ->{-1}, ->{-1}, ->{1}, ->{0});</langsyntaxhighlight>
 
=={{header|Smalltalk}} ==
 
Number>>x1: x1 x2: x2 x3: x3 x4: x4 x5: x5
Line 3,065 ⟶ 3,344:
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,080 ⟶ 3,359:
}
 
print(a({ "k": 10 }, x(1), x(-1), x(-1), x(1), x(0)));</langsyntaxhighlight>
 
=={{header|Standard ML}}==
Line 3,086 ⟶ 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,100 ⟶ 3,379:
 
val () =
print (Int.toString (a (10, fn () => 1, fn () => ~1, fn () => ~1, fn () => 1, fn () => 0)) ^ "\n")</langsyntaxhighlight>
 
=={{header|Swift}}==
Line 3,107 ⟶ 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,127 ⟶ 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,142 ⟶ 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,157 ⟶ 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,172 ⟶ 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,330 ⟶ 3,609:
END
 
</syntaxhighlight>
</lang>
 
Outputs:
Line 3,342 ⟶ 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,348 ⟶ 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,361 ⟶ 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,373 ⟶ 3,652:
The complete code follows:
 
<langsyntaxhighlight lang="txrlisp">(defstruct (cbn-thunk get set) nil get set)
 
(defmacro make-cbn-val (place)
Line 3,440 ⟶ 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,448 ⟶ 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,470 ⟶ 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,503 ⟶ 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.
<langsyntaxhighlight ecmascriptlang="wren">import "./fmt" for Fmt
 
var a
Line 3,522 ⟶ 3,802:
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 }))
}</langsyntaxhighlight>
 
{{out}}
Line 3,548 ⟶ 3,828:
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,567 ⟶ 4,040:
A(k, B, x1, x2, x3, x4);
}
}</langsyntaxhighlight>
{{out}}
<pre>
Anonymous user