Skip to content

Instantly share code, notes, and snippets.

@ftdysa
Forked from beberlei/tailrecursion.php
Created January 28, 2014 23:44
Show Gist options
  • Save ftdysa/8678961 to your computer and use it in GitHub Desktop.
Save ftdysa/8678961 to your computer and use it in GitHub Desktop.
<?php
class TailRecursion
{
public $func;
public $acc;
public $recursing;
public function tail()
{
return call_user_func_array($this->func, func_get_args());
}
public function getClosure($fn)
{
$this->acc = array();
$this->recursing = false;
$fn = $fn->bindTo($this);
return $this->func = function() use ($fn) {
$this->acc[] = func_get_args();
if ( ! $this->recursing) {
$this->recursing = true;
while ($this->acc) {
$ret = call_user_func_array($fn, array_shift($this->acc));
}
$this->recursing = false;
return $ret;
}
};
}
}
function tailrec($func)
{
$tail = new TailRecursion();
return $tail->getClosure($func);
}
$fac = tailrec(function($n, $acc = 1) {
if ($n == 1) {
return $acc;
}
return $this->tail($n - 1, $acc * $n);
});
echo $fac(4); // 1 * 2 * 3 * 4 = 24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment