Skip to content

Instantly share code, notes, and snippets.

@billhails
Created June 30, 2018 10:55
Show Gist options
  • Save billhails/fc9d612afc110d5bdc495eceb20bc973 to your computer and use it in GitHub Desktop.
Save billhails/fc9d612afc110d5bdc495eceb20bc973 to your computer and use it in GitHub Desktop.
examples of continuation-passing style in PHP
<?php
function factorial($n) {
if ($n === 0) {
return 1;
} else {
return $n * factorial($n - 1);
}
}
print(factorial(3));
print("\n");
<?php
function factorial($n) {
return factorialHelper($n, 1);
}
function factorialHelper($n, $a) {
if ($n === 0) {
return $a;
} else {
return factorialHelper($n - 1, $n * $a);
}
}
print(factorial(3));
print("\n");
<?php
function factorial($n, $c) {
if ($n === 0) {
$c(1);
} else {
factorial($n - 1, function ($v) use ($c, $n) { $c( $n * $v); });
}
}
factorial(3, function ($v) { print($v); });
print("\n");
<?php
function factorial ($n, $c) {
factorialHelper($n, 1, $c);
}
function factorialHelper($n, $a, $c) {
if ($n === 0) {
$c($a);
} else {
factorialHelper($n - 1, $n * $a, $c);
}
}
factorial(3, function ($v) { print($v); });
print("\n");
<?php
function p($v) { print($v . "\n"); }
function a() { p("a"); m(); p("a"); x(); p("a"); }
function m() { p("m"); n(); p("m"); }
function n() { p("n"); }
function x() { p("x"); y(); p("x"); }
function y() { p("y"); }
a();
<?php
function p($v) { print($v . "\n"); }
function a($c) { p("a"); m(function () use($c) { p("a"); x(function () use($c) { p("a"); $c(); }); }); }
function m($c) { p("m"); n(function () use($c) { p("m"); $c(); }); }
function n($c) { p("n"); $c(); }
function x($c) { p("x"); y(function () use($c) { p("x"); $c(); }); }
function y($c) { p("y"); $c(); }
a(function () {});
<?php
$s = 0;
function p($v) { print($v . "\n"); }
function a($c) { p("a"); m(function () use($c) { p("a"); x(function () use($c) { p("a"); $c(); }); }); }
function m($c) { p("m"); n(function () use($c) { p("m"); $c(); }); }
function n($c) { global $s; $s = $c; p("n"); $c(); }
function x($c) { p("x"); y(function () use($c) { p("x"); $c(); }); }
function y($c) { p("y"); global $s; $s(); }
a(function () {});
<?php
function factorial($n, $c) {
if ($n === 0) {
return function () use ($c) { return $c(1); };
} else {
return function () use ($c, $n) {
return factorial(
$n - 1,
function ($v) use ($c, $n) {
return function () use ($c, $n, $v) { return $c($n * $v); };
}
);
};
}
}
function trampoline($t) {
while (isset($t)) {
$t = $t();
}
}
trampoline( function () { return factorial(3, function ($v) { print($v); return null; }); });
print("\n");
<?php
function factorial($n, $c) {
return function () use($n, $c) { return factorialHelper($n, 1, $c); };
}
function factorialHelper($n, $a, $c) {
if ($n === 0) {
return function () use ($c, $a) { return $c($a); };
} else {
return function () use ($c, $n, $a) {
return factorialHelper($n - 1, $n * $a, $c);
};
}
}
function trampoline($t) {
while (isset($t)) {
$t = $t();
}
}
trampoline(function () { return factorial(10, function ($v) { print($v); return null; }); });
print("\n");
<?php
function p($_) {
$args = func_get_args();
print(implode(" ", $args) . "\n");
}
function factorial($id, $n, $c) {
p($id, $n);
if ($n === 0) {
return function () use ($c) { return $c(1); };
} else {
return function () use ($id, $c, $n) {
return factorial(
$id,
$n - 1,
function ($v) use ($c, $n) {
return function () use ($c, $n, $v) { return $c($n * $v); };
}
);
};
}
}
function trampoline($q) {
while (count($q)) {
$t = array_shift($q);
$t = $t();
if (isset($t)) {
array_push($q, $t);
}
}
}
trampoline(
[
function () { return factorial("a", 1, function ($v) { p("==> $v"); return null; }); },
function () { return factorial("b", 6, function ($v) { p("==> $v"); return null; }); }
]
);
<?php
function factorial($label, $n, $continuation) {
return factorialHelper($label, $n, 1, $continuation);
}
function factorialHelper($label, $n, $accumulator, $continuation) {
print("$label: $n ($accumulator)\n");
if ($n === 0) {
return function () use ($continuation, $accumulator) {
return $continuation($accumulator);
};
} else {
return function () use ($label, $continuation, $n, $accumulator) {
return factorialHelper(
$label,
$n - 1,
$n * $accumulator,
$continuation
);
};
}
}
function trampoline($queue) {
while (count($queue)) {
$thread = array_shift($queue);
$thread = $thread();
if (isset($thread)) {
array_push($queue, $thread);
}
}
}
function makeThread($label, $n) {
return function () use ($label, $n) {
return factorial(
$label,
$n,
function ($v) use($label, $n) {
print("$label: factorial of $n is $v\n");
return null;
}
);
};
}
trampoline(
[
makeThread("thread A", 2),
makeThread("thread B", 4),
makeThread("thread C", 6)
]
);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment