
Recursion, Tail Calls and Trampolines - tuxz0r
http://www.datchley.name/recursion-tail-calls-and-trampolines/
======
kazinator
Portable tail recursion for Common Lisp:

[http://www.kylheku.com/cgit/lisp-snippets/tree/tail-
recursio...](http://www.kylheku.com/cgit/lisp-snippets/tree/tail-
recursion.lisp)

The lexical tlet construct doesn't use trampolines; it translates to
tagbody/go. It is built on the argtags macro (early in the file), which
provides an abstraction similar to tagbody/go, but where the labels can take
parameters, and GO passes parameters to labels. The parameters are just
variable assignments, of course. If you (goto foo 1 2 3) and there is a (label
foo x y z), it means that control passes to that label, and the variables x y
z take on values 1 2 3.

deftail is for tail recursion among independent functions. It is based on
trampolines. The :other-tails keyword is used to declare which other functions
participate. When the deftail function calls these others, those calls are
assumed to be tail calls. You can also use the tail-call function explicitly
(as a replacement for funcall) to abandon execution up to the trampoline loop
and call a given function.

tail-call is the heart of the trampoline. It first checks whether it is
already dynamically enclosed in a trampoline, and if so, it just uses that one
to do the tail call. Otherwise it establishes a new dynamic contour and enters
into the trampoline loop.

Thus any of the tail functions can be entered as ordinary functions. Then when
they tail out to their peers, they establish the trampoline context.

~~~
junke
Thanks for sharing this.

------
richdougherty
Shout out to WebKit for being the first web browser to support tail calls in
its JavaScript engine:

[https://www.webkit.org/blog/4054/es6-in-
webkit/](https://www.webkit.org/blog/4054/es6-in-webkit/)

Come on other browsers!

[https://kangax.github.io/compat-table/es6/#test-
proper_tail_...](https://kangax.github.io/compat-table/es6/#test-
proper_tail_calls_\(tail_call_optimisation\))

------
taylodl
Since ES6 doesn't generally support TCO Id recommend using Babel. I wrote
about Babel's ability to support TCO, and its downsides, here: Functional
JavaScript – [https://taylodl.wordpress.com/2015/08/09/functional-
javascri...](https://taylodl.wordpress.com/2015/08/09/functional-javascript-
tail-call-optimization-and-babel/)

