问题标签 [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 回答
80 浏览

c - 使用蹦床避免堆栈溢出

下面程序中的蹦床功能正常工作。我认为下面的程序会导致堆栈溢出,因为函数 thunk_f 和 thunk1 无限期地相互调用,从而导致创建新的堆栈帧。但是,我想编写一个行为更类似于非终止循环的程序,因为蹦床应该防止堆栈溢出。

0 投票
1 回答
130 浏览

c - 使用带有一个函数的蹦床作为参数

我知道蹦床函数是什么,但我一直无法使用蹦床避免堆栈溢出。到目前为止,我能想到的唯一方法是使用全局变量,这是不鼓励的,并且会使程序复杂化。

我想使用的蹦床功能如下图所示。

当我尝试传入带有参数的函数时,例如下面代码片段中的那些,我最终会创建堆栈,这不是我想要的。我想知道是否有一种方法可以在不使用全局变量或传入任何额外参数的情况下使用我的蹦床函数?

下面的程序按照我想要的方式运行,但是它使用了一个全局变量,这被广泛反对。

澄清:我不想修改上面的蹦床功能,但我想减少堆栈创建。

0 投票
2 回答
474 浏览

javascript - LeetCode #70 爬楼梯,如何加快我的解决方案?

我在 LeetCode #70 爬楼梯上有这个问题的解决方案,我的解决方案没有通过,因为它很慢......

我已经添加了一个使用 thunk 的蹦床,并且我已经添加了记忆,我还可以添加什么来加速它以实际通过这个问题的时间要求,我的代码如下,并提前感谢。

LeetCode 上的描述:

你正在爬楼梯。到达顶部需要 n 步。

每次您可以爬 1 或 2 级台阶。你可以通过多少种不同的方式爬上顶峰?

注意:给定 n 将是一个正整数。

LeetCode 上的问题链接:https ://leetcode.com/problems/climbing-stairs/

0 投票
1 回答
343 浏览

windows - 如何安全地包装回调以传递给 Windows FFI?

我正在尝试在 winapi 之上编写一个包装器。我想包装接受回调函数指针的函数。

例如,考虑一下:

将使用的功能:

我想创建一个如下所示的包装函数:

我可以想到创建这个包装函数的两种可能性:

  1. 在运行时创建包装函数

    SetExceptionHandler在安全方法中创建一个闭包或类似的构造 。

    我不知道如何关闭 FFI 边界。

  2. 公开转换宏并在编译时生成函数

    编辑SetExceptionHandler函数以接受UnsafeCallback 类型。

    然后我可以创建一个在编译时生成包装函数的宏,并将这个宏公开给用户。

    我将不得不再次公开不安全的外部参数,所以这不是我希望这样做的方式。

    我不知道如何构建这样的宏,或者这是否可能。


我的第一个想法可能可行吗?如果是这样,如何做到这一点?如果不是,那么编写像第二个想法这样的宏是否可行且可行?如果是这样,如何做到这一点?

基于

我的印象是,除了蹦床之外,我的第一个想法可能是不可能的。

在安全的 Rust 和这种情况下,蹦床是可能的吗?

0 投票
1 回答
152 浏览

python - 当解释器循环本身是递归的时蹦床的堆栈安全性

我正在 Python 中实现 Trampoline,以便编写具有堆栈安全性的递归函数(因为 CPython 不具有 TCO)。它看起来像这样:

现在,我需要一个单子序列运算符。我最初的看法是这样的:

这行得通,但是以这种方式减少一长串蹦床所导致的所有函数调用的开销绝对会降低性能。

所以我尝试了这个:

现在,我的直觉是,第二个解决方案sequence不是堆栈安全的,因为它调用的是run,这意味着run它将run在解释期间调用(通过Call.thunk但不少于)。但是,无论我如何混搭,我似乎都无法产生堆栈溢出。

例如,我认为应该这样做:

我尝试了无数其他示例,但没有堆栈溢出。我的直觉仍然认为这是行不通的。

我需要有人说服我以这种方式蹦床解释器循环实际上是堆栈安全的,或者向我展示一个溢出堆栈的示例

0 投票
1 回答
490 浏览

scala - 在 ZIO 中设置默认执行上下文

我正在尝试在 ZIO 中使用 TrampolineExecutionContext 来测试同一线程上的后台流订阅(这样我就可以按照我期望的顺序运行效果)。

在这种情况下,我得到了我所期望的:

《在流元素中》、《深入理解》

如果我删除on(trampolineExecutionContext),我将仅因为我没有加入光纤(创建同步点)而获得“内部理解”。

如何为整个测试将默认上下文设置为 trampolineExecutionContext 而无需在每次调用或重要调用中都重复它?

0 投票
3 回答
147 浏览

javascript - 使用蹦床从嵌套数组创建树并将其转换为字符串

我想用蹦床用 JavaScript 重写我的 lisp 中的所有递归函数。我有两个例子我不知道如何重写:

这是蹦床代码:

问题是它不起作用,如果调用 trampolined 函数,它会重载堆栈,从 trampoline 调用返回的值,当我调用命名函数表达式时,我得到:(1 #<Thunk>)。我试过放unwind(pair_to_string(pair.cdr, quote, true)),但这也会使堆栈超载。

这个函数可以用 trampoline 编写,以便将 lisp 列表转换为字符串吗?

这是具有这两个功能的堆栈片段。我知道我需要编写看起来像尾递归但返回 Thunk 的函数,但如果我在创建表达式的过程中该怎么做。

注意:上面的代码已经重构了没有任何蹦床的原始功能(蹦床代码包含但未使用)。

PS:我也可以使用其他解决方案,它允许在不使用递归和消耗堆栈的情况下遍历二叉树。如果您不能使用蹦床遍历二叉树,我也可以解释为什么这是不可能的。但更喜欢实际的解决方案。

0 投票
1 回答
169 浏览

javascript - 基于蹦床的链表(lisp 树)到带循环的字符串

我的基于蹦床的函数对 lisp 列表进行字符串化有问题。这是代码:

问题是缺少最后一个括号,我不确定我应该如何在蹦床上使用延续来解决问题。

这是在没有蹦床的情况下工作的代码:

我有两个案例应该适用于第一个大列表(8000 个元素)和小循环。使用堆栈片段中的代码,它适用于长列表,但不适用于没有蹦床的循环,它会溢出大列表上的堆栈。它也是 lisp,所以它需要在任何树上工作,而不仅仅是链表。

编辑:如果您尝试回答,请至少不要更改数据结构。它需要是与 car 和 cdr 配对的类,并且需要在将它们转换为字符串之前计算周期。所以它可以与多个函数一起检查内存中的数据是否是循环的。

0 投票
1 回答
122 浏览

javascript - 如何更有效地使用 Trampoline 类型作为变压器的基本单子?

我有一个数组转换器类型,它展示交错的效果层,以确保合法的效果实现。of您可以轻松地从类型的操作中读取结构const arrOfT = of => x => of([of(x)])

该类型实现了一个有效的折叠作为它的基本操作。我使用左折叠,因为底层数组类型本质上是严格的:

如您所见,该实现不是堆栈安全的。然而,堆栈安全只是另一个可以通过 monad 编码的计算效果。我为以下类型实现了一个Trampoline

虽然实现很简单,但应用程序却不是。我很确定我完全错误地应用了它:

我需要Chain在创建大型有效数组时使用,因为Of发出控制流突破蹦床的信号。Chain另一方面,我必须指定一个多余的延续。

我的第一个想法是翻转Chain的论点并依赖于部分应用,但这不适用于当前的实现。

有没有办法更有效地使用类型?

这是一个工作示例:

0 投票
1 回答
120 浏览

javascript - 如何将 TaskT 与 Trampoline 的 monad 实例结合起来进行无堆栈异步计算?

Trampoline是一个单子,并为单子变压器堆栈增加了堆栈安全性。它通过依赖一个特殊的解释器monadRec(出于这个原因,Trampolinemonad 必须是最外层的 monad,即变压器堆栈的基本 monad。

在以下设置中TaskT(本质Cont上是共享)是 monad 转换器和Trampoline基本 monad:

这不是我想要的,因为在Trampoline事件循环接收异步任务的结果之前强制评估。我需要的是相反的方式,但正如我已经提到的,没有TrampolineT变压器。我错过了什么?