Tail Recursion Utilities
by Dave Herman (dherman at ccs dot neu dot edu)
This library provides utilities for tail recursion.
(require (planet dherman/tail:5:0)) |
1 Disabling Tail Recursion
(trace-begin body-expr ...+) |
(trace-app expr ...+) |
(require (rename-in (planet dherman/tail:5:0) [trace-app #%app]))
Subsequent function applications appearing within the body of the module are then translated to non-tail calls.
2 Tail-Recursive Continuations
| |
|
The identifier k-id is bound to a special form that invokes the captured continuation in tail position with respect to the entire let/tc expression.
Examples: | ||||||
| ||||||
> (down 10) | ||||||
(0 1 2 3 4 5 6 7 8 9 10) | ||||||
| ||||||
> (down* 10) | ||||||
(0) |
To achieve proper tail recursion, the argument to k-id is evaluated in the hole of the captured continuation, i.e., after abandoning the current continuation. Note that this behavior is significant when the argument expression performs side effects.
Examples: | ||||
| ||||
(before) | ||||
| ||||
(after) | ||||
| ||||
caught | ||||
| ||||
uncaught |
The captured continuation k-id can only be applied to exactly one argument. (If control returns normally, i.e., without explicitly invoking k-id, it may return any number of values.)
Examples: | ||
| ||
eval:11:0: k: bad syntax in: (k 1 2 3) | ||
| ||
1 | ||
2 | ||
3 |
3 Generalized Continuation Marks
(with-continuation-mark* key-expr val-expr update-expr body-expr ...+) |
Example: | ||||
| ||||
(9) |