Ngoài ra còn có cảm giác LISP về 'tấm bạt lò xo' như được mô tả trên Wikipedia:
Được sử dụng trong một số triển khai LISP, tấm bạt lò xo là một vòng lặp gọi lặp đi lặp lại các hàm thunk-return. Một tấm bạt lò xo duy nhất là đủ để thể hiện tất cả các chuyển điều khiển của một chương trình; một chương trình được thể hiện như vậy được trampolined hoặc theo "kiểu trampolined"; chuyển đổi một chương trình sang kiểu trampolined là trampolining. Các hàm trampolined có thể được sử dụng để thực hiện các lệnh gọi hàm đệ quy đuôi trong các ngôn ngữ hướng ngăn xếp
Giả sử chúng tôi đang sử dụng Javascript và muốn viết hàm Fibonacci ngây thơ theo kiểu tiếp diễn. Lý do chúng tôi làm điều này không liên quan - chẳng hạn như chuyển Đề án sang JS hoặc để chơi với CPS mà chúng tôi vẫn phải sử dụng để gọi các hàm phía máy chủ.
Vì vậy, nỗ lực đầu tiên là
function fibcps(n, c) {
if (n <= 1) {
c(n);
} else {
fibcps(n - 1, function (x) {
fibcps(n - 2, function (y) {
c(x + y)
})
});
}
}
Tuy nhiên, chạy điều này với n = 25
trong Firefox sẽ xuất hiện lỗi 'Quá nhiều đệ quy!'. Bây giờ đây chính xác là vấn đề (thiếu tối ưu hóa cuộc gọi đuôi trong Javascript) mà trampolining giải quyết. Thay vì thực hiện một cuộc gọi (đệ quy) đến một hàm, hãy để chúng tôi return
một lệnh (thunk) để gọi hàm đó, được diễn giải trong một vòng lặp.
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]});
}