还有 LISP 对“蹦床”的理解,如 Wikipedia 上所述:
在一些 LISP 实现中使用,a
蹦床是一个循环迭代
调用 thunk-returning 函数。一种
单人蹦床就足够了
表达所有控制权转移
程序;这样表达的程序是
蹦床或“蹦床式”;
将程序转换为蹦床
风格是蹦床。蹦床
函数可以用来实现
尾递归函数调用
面向堆栈的语言
假设我们正在使用 Javascript,并且想要以连续传递样式编写简单的斐波那契函数。我们这样做的原因无关紧要——例如将 Scheme 移植到 JS,或者使用 CPS,无论如何我们都必须使用它来调用服务器端函数。
所以,第一次尝试是
function fibcps(n, c) {
if (n <= 1) {
c(n);
} else {
fibcps(n - 1, function (x) {
fibcps(n - 2, function (y) {
c(x + y)
})
});
}
}
但是,在 Firefox 中使用 n = 25 运行它会出现错误“递归过多!”。现在这正是蹦床解决的问题(Javascript 中缺少尾调用优化)。与其对函数进行(递归)调用,不如让我们return 一条指令(thunk)来调用该函数,并在循环中进行解释。
function fibt(n, c) {
function trampoline(x) {
while (x && x.func) {
x = x.func.apply(null, x.args);
}
}
function fibtramp(n, c) {
if (n <= 1) {
return {func: c, args: [n]};
} else {
return {
func: fibtramp,
args: [n - 1,
function (x) {
return {
func: fibtramp,
args: [n - 2, function (y) {
return {func: c, args: [x + y]}
}]
}
}
]
}
}
}
trampoline({func: fibtramp, args: [n, c]});
}