【问题标题】:Limit the recursion level in a Clojure repl限制 Clojure repl 中的递归级别
【发布时间】:2015-05-06 14:03:44
【问题描述】:

在 repl 中工作时,有一种方法可以指定在 repl 自动结束表达式计算之前重复的最大次数。例如,假设以下函数:

(defn looping []
  (loop [n 1]
    (recur (inc n))))

(looping)

有没有办法指示 repl 在 100 级递归后放弃?类似于print-level

【问题讨论】:

  • 这是否类似于在 repl 中使用 Ctrl-C 的默认行为?在我的场景中,调用 set-break-handler! 后我没有注意到有什么不同!在无限递归中并使用 Ctrl-C 时,repl 不会被中断,递归会继续。

标签: recursion clojure read-eval-print-loop


【解决方案1】:

我恭敬地希望我没有忽视你问题的精神,但为什么不简单地使用 when 表达式呢?它简洁明了,根本不会改变函数的主体(1 行额外的行和结束括号)。

虽然我不相信你想要的存在,但实现你自己的将是微不足道的:

(def ^:dynamic *recur-limit* 100)

(defn looping []
  (loop [n 1]
    (when (< n *recur-limit*)
      (recur (inc n)))))

大概这还没有被添加到语言中,因为使用现有的语言原语很容易构建你需要的东西;除此之外,如果该设施确实存在但“不可见”,则可能会导致大量混乱和错误,因为代码并不总是以可预测和引用透明的方式运行。

【讨论】:

  • 我希望防止意外的无限递归。碰巧我没有正确指定终端条件。然后 repl 陷入无限递归,我无法取消它,所以我最终不得不杀死整个 repl,至少。因此,当我启动 repl 时,最好指定一个递归级别作为安全防护以防止这种情况发生。
  • 这是不可能的,因为recur 编译为goto
  • 你能扩展一下吗?我假设打印级别和类似级别可以正常工作,因为打印机会计算已打印的级别并在指定级别停止。在这种情况下,书面代码相当于打印机,因此它负责计数,其方式类似于 @scott-lowe 所说的。还是有更多的东西?
猜你喜欢
  • 1970-01-01
  • 2012-07-15
  • 1970-01-01
  • 1970-01-01
  • 2020-07-31
  • 2014-04-02
  • 1970-01-01
  • 2013-05-15
  • 1970-01-01
相关资源
最近更新 更多