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.