【发布时间】:2013-04-10 06:26:39
【问题描述】:
为什么最后一个表达式永远卡在 nrepl 中(我猜它永远不会停止)。 我必须 Ctrl+c Ctrl+c 才能停止它。
【问题讨论】:
为什么最后一个表达式永远卡在 nrepl 中(我猜它永远不会停止)。 我必须 Ctrl+c Ctrl+c 才能停止它。
【问题讨论】:
因为您正在尝试评估无限序列(通过将其打印到 REPL)。
例如的结果(filter #(> % 100) (iterate #(+ % 17) 0)) 可以打印到 REPL,因为 REPL 将打印结果序列的第一个 x 元素,然后是 ...,其中 x 是您可以使用 (set! *print-length* x) 设置的值。
但尝试评估(filter #(< % 100) (iterate #(+ % 17) 0)) 将永远运行,因为只有 6 个可能的元素。
查看*print-length* 文档:
;; Oops! Don't this!!!
user=> (iterate inc 0)
;; Frantically doing C-c C-c :-P
; Evaluation aborted.
user=> (set! *print-length* 10)
10
;; Now it's perfectly fine. Yay!
user=> (iterate inc 0)
(0 1 2 3 4 5 6 7 8 9 ...)
您可能想要使用take-while 而不是filter,因为您使用iterate 创建的序列已经排序。
user=> (take-while #(< % 100) (iterate #(+ % 17) 0))
(0 17 34 51 68 85)
【讨论】:
x 元素。 REPL 无法知道获取这些元素需要多少时间,或者是否有可能。此外,您的序列不是有限的。
take-while 代替过滤器。查看我的更新。
如上面的表达式response中打印的序列不是完整的结果(检查序列末尾的...),这表明nrepl在返回一个序列的响应时take具体的项目数来自序列并用 ... 打印它们以指示序列中还有更多。在你的最后一种情况下,“少于 100 个数字”不会产生 nrepl 打印所需的最小项目数,因此 nrepl 继续等待序列中的更多项目(这是一个无限序列,因为迭代)
【讨论】:
您的序列中只有 3 个数字小于 100。但是,由于它是“无限”的,filter 必须查看“无限”个元素来确定第四个元素不存在。
由于您的示例 iterate 构造生成一个递增序列,如果您想将结果限制为小于 100 个的元素,您可以使用 take-while。例如:
(take-while #(< % 100) (iterate #(+ % 17) 0))
【讨论】: