NAME

FP::Trampoline -- tail call optimization without reliance on goto

SYNOPSIS

use FP::Trampoline; # exports `T` and `trampoline`

sub iterative_fact {
    my ($n,$tot) = @_;
    $n > 1 ? T{ iterative_fact ($n-1, $tot*$n) } : $tot
    # or
    # $n > 1 ? TC \&iterative_fact, $n-1, $tot*$n : $tot
}
sub fact {
    my ($n) = @_;
    trampoline iterative_fact ($n, 1)
}
is fact(5), 120;

use FP::Stream;
is( fact(20), stream_iota(2)->take(19)->product );

DESCRIPTION

Perl has direct support for optimized (i.e. non-stack-eating) tail calls, by way of `goto &$subref`, but there are still bugs in current versions of Perl with regards to memory handling in certain situations (see "perl/goto-leak" in t). Trampolining is a technique that works without reliance on any tail call optimization support by the host language. Its drawbacks are more overhead and the requirement to put a `trampoline`ing call around any function that employs trampolining.

FUNCTIONS

T { ... }

Returns a closure blessed into the `FP::Trampoline::Continuation` namespace, which represents a trampolining continuation.

TC $fn, $arg1...

Returns a `FP::Trampoline::Call` object, which represents the same thing, but can only be used for a call ('Trampoline Call'). The advantage is that the arguments for the call are evaluated eagerly, which makes it work for dynamic variables, too (like `$_` or local'ized globals). It may also be a bit faster.

trampoline ($value)

The trampoline that bounces back as long as it receives a trampolining continuation: if so, the continuation is run, and the result passed to the `trampoline` again, otherwise it is returned directly.

NOTE

This is alpha software! Read the status section in the package README or on the website.