问题标签 [trampolines]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
1 回答
379 浏览

scala - 斯卡拉猫蹦床

test("ok") 是从 Noel Welsh 和 Dave Gurnell 第 254 页("D.4 Safer Folding using Eval")的书 "scala with cats" 中复制的,代码运行良好,它是蹦床 foldRight

test("ko") 为小列表返回相同的 test("ok") 值,但对于长列表,该值不同。为什么?

0 投票
1 回答
66 浏览

c++ - 将回调从 C++ 转发到 ObjC

我正在使用 .mm (ObjC++) 将 C++ 引擎嵌入到 ObjC iOS 项目中。

即我们设置cppEngine给它一个回调;这里是一个 C++ lambda。

当引擎触发回调时,我们必须将数据传回给消费者。

我的问题是:什么是正确的架构来做到这一点?我不认为[targ sel: data];是有效的目标 C。即使是,我也不确定 aSEL是否会通过 lambda 的捕获。它甚至是一个有效的 C++ 对象吗?

我可以通过以下方式中的静态方法蹦床来看到一种方法wrapper.mm

...但这开始看起来很恶心。

0 投票
0 回答
222 浏览

c++ - 如何计算正确的大小以复制到蹦床上

我正在尝试在 x64 位窗口中挂钩函数我可以轻松地挂钩目标函数,但问题是在创建蹦床时我需要知道合适的大小才能从原始函数复制到蹦床,然后将 jmp 指令复制到目标

这是我的补丁字节:

我将目标地址的地址放入其中并将其复制到蹦床的末尾,蹦床将跳转到挂钩函数的地址+复制的字节

但有时我会遇到一些错误,例如访问冲突,因为说明不正确,所以我需要知道如何获得正确的复制大小并跳转到它之后的字节

0 投票
1 回答
99 浏览

javascript - 堆栈安全的相互递归,不会在调用端泄露实现细节

我概括了clojure的loop/recur蹦床,以便它与间接递归一起工作:

但是,我必须在调用方显式调用蹦床。有没有办法让它再次隐含,就像loop/一样recur

顺便说一句,这里是loop/ recur

0 投票
1 回答
292 浏览

javascript - Trampoline 递归导致“超出最大调用堆栈大小”

我正在研究区块链,并且正在实施一个非常简单的“工作证明”。

工作证明:

蹦床:

我仍然收到“超出最大调用堆栈大小”错误,甚至是蹦床mine功能。

我在 StackOverflow 上阅读了很多其他问题以及各种博客上的文章,但其中很多只关注“阶乘”或“斐波那契”示例,其中蹦床或 TCE 解决了问题……但事实并非如此。

我正在使用 Node 10,所以我不介意这在浏览器中是否不起作用。

0 投票
0 回答
391 浏览

c++ - 使用 detours 时防止递归挂钩

我想通过使用 API 挂钩所有 ntdll 函数来构建某种 API 监视器Detours。每个挂钩函数将调用原始实现,然后在 std 基本数据结构中添加此调用的通知。

但是,我遇到了一个递归挂钩的场景,我的挂钩函数间接调用了自己。

因此,我尝试使用 Tls 内存为每个线程设置一个位,指示当前函数是从钩子函数调用的,因此避免再次调用钩子(仅执行原始函数)。

但是我的递归钩子守卫也使用了一些内存分配函数的调用NtAllocateVirtualMemory,因此我目前正在避免挂钩这些函数。

也许有人遇到过类似的问题并以不触发任何内存分配函数的方式实现了钩子重入保护(这可能是不可能的,因为即使您调用一个新函数并且您的堆栈内存不足,它也应该分配更多内存) .

谢谢

0 投票
1 回答
342 浏览

recursion - Groovy 的 trampoline() 使递归执行更慢 - 为什么?

我正在尝试递归:

如果我像这样使用它,我会得到这个:

在 691 毫秒内完成

如果我取消注释第 2 行和第 3-4 行注释以删除trampoline()并运行它,我得到的数字要低得多:

在 335 毫秒内完成

因此,使用蹦床时,递归的工作速度要慢 2 倍。

我错过了什么?

附言

如果我在 Scala 2.12 中运行相同的示例:

它执行得更快一点:

在 178 毫秒内完成

更新

将闭包重写为带有注解的方法:

在 164 毫秒内完成

并且是超级科尔。尽管如此,我仍然想知道trampoline():)

0 投票
0 回答
349 浏览

python - 在 python 中使用 thunk、trampolines 和延续传递

我从这个博客了解了尾调用优化(TCO)的概念:给我唱一首 Stack Overflow 之歌:音乐尾调用优化

进入这个概念(或“功能”或“优化技术”),我开始知道在 python 中使用 TCO 并不是一种 Python 的方式,正如 Guido 解释的那样:

http://neopythonic.blogspot.com/2009/04/tail-recursion-elimination.html http://neopythonic.blogspot.com/2009/04/final-words-on-tail-calls.html

进一步检查后发现 James Tauber 的博客讨论了 James Tauber 的Thunks、Trampolines 和 Continuation 传递 Thunks、Trampolines 和 Continuation 传递

James Tauber 展示了如何使用 Thunks、Trampolines 和 Continuation 传递来解决递归函数的堆栈调用问题,但解释有些难以掌握。

所以,这里有一些我想澄清的问题:

  1. 这里的任何人都可以对这些概念提供一个可以理解的解释吗?
  2. 这个概念是试图在 python 中实现 TCO 还是与 TCO 不同?
  3. 由于 Guido 将 TCO 称为not a pythonic way因为 TCO 没有给出适当的回溯,那么这个概念是否Thunks, Trampoline and Continuation passing满足保留回溯的要求?
0 投票
3 回答
662 浏览

javascript - 如何使蹦床适应延续传球风格?

这是正确折叠的简单实现:

这是非尾递归,因此我们不能应用蹦床。一种方法是使算法迭代并使用堆栈来模仿函数调用堆栈。

另一种方法是将递归转换为 CPS:

这仍然很幼稚,因为它非常缓慢。这是一个内存消耗较少的版本:

递归调用现在处于尾部位置,因此我们应该能够应用我们选择的蹦床:

这不起作用,因为蹦床调用在延续内部,因此被懒惰地评估。蹦床必须如何适应才能与 CPS 一起使用?

0 投票
1 回答
264 浏览

javascript - 蹦床的奇怪行为

最近在codewars上做一些JS任务,遇到了这个任务Tail recursion with trampoline。这里我们需要创建 thunk 函数和 trampoline 函数来摆脱恼人的 RangeError: Maximum call stack size exceeded。所以我尝试了这段代码:

这没有用,仍然有 RangeError。但是在我将 console.log() 添加到 _isOdd 或 _isEven 之后,它不会抛出错误并通过所有测试。像这样:

我理解错误并重写了代码,但不明白为什么添加console.log()时它会起作用。