Friday, January 6, 2012

Tail recursion in Python

Admittedly, not the most "pythonic" code, whatever that means...

#!/usr/bin/python

from inspect import isfunction

recur = 0

def loop(func):
  def inner(a,b):
    global recur
    old_recur = recur
    recur = lambda a,b: lambda:func(a,b)
    ret = func(a,b)
    while isfunction(ret):
      ret = ret()
    recur = old_recur
    return ret
  return inner

Which creates a nice decorator:

@loop
def foo(n, a):
  if n == 0:
    return a
  else:
    return recur(n-1,a*n)

print(foo(6,1))

Thursday, January 5, 2012

Tail recursion in Perl

I finally get to use local! This really should be wrapped up in some type of module, but it is getting late.

#!/usr/bin/perl -w

$recur = 0;

sub loop($) {
    my ($func) = @_;

    sub {
        local $recur = sub {
            my @args = @_;
            sub { $func->(@args); }
        };

        my $ret = $func->(@_);
        while ('CODE' eq ref($ret)) {
           $ret = $ret->(); 
        }
        $ret;
    };
}


Example usage:
my $foo = loop sub {
    my ($n, $a) = @_;
    if ($n == 0) {
        $a;
    }
    else {
        $recur->($n-1, $a*$n);
    }
};

print $foo->(999999,1) . "\n";

Tail recursion in Groovy

Groovy ships with a limited form of tail recursion via a trampoline mechanism. Here, I expand on the existing trampoline to add a cleaner, more intuitive interface. This extension has two parts: a Java class and a new Object method (read: global function).

A Java class:
import groovy.lang.Closure;
// loop/recur

class RecursionWrapper {
    private Closure<object> _target;

    public RecursionWrapper(Closure<object> target) {
     _target = target;
    }
    
    public Object recur() {
        return _target.trampoline();
    }
    public Object recur(Object a) {
        return _target.trampoline(a);
    }
    public Object recur(Object... a) {
        return _target.trampoline(a);
    }
}

A global function:
// loop/recur

Object.metaClass.loop = {closure->
 def cln = closure.clone()
 def trCln = cln.trampoline()
 def rw = new RecursionWrapper(trCln)
 cln.delegate = rw
 trCln
}

Tail recursion

To restart my blogging, I will be writing a short series of posts on adding Clojure style loop/recur tail recursion to other languages. Code will generally come first and I will fill in details as I have time.