为什么过滤器卡在nrepl?

时间:2013-04-10 06:26:39

标签: clojure nrepl

enter image description here

为什么最后一个表达式在nrepl中永远停留(我猜它永远不会停止)。 我必须按Ctrl + c Ctrl + c来停止它。

3 个答案:

答案 0 :(得分:3)

因为您正在尝试评估无限序列(通过将其打印到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)

答案 1 :(得分:0)

如上面的表达式所示,响应打印的序列不是完整的结果(检查序列末尾的......),这表明nrepl在返回序列take特定数量的响应时序列中的项目并用...打印它们以表示序列中还有更多项目。在你的最后一种情况下,“少于100个数字”将不会产生nrepl打印所需的最小项目数,因此nrepl继续等待序列中的更多项目(这是迭代的无限序列becoz)

答案 2 :(得分:0)

序列中只有3个数字小于100.但是,由于它是“无限”,filter必须查看“无限”数量的元素以确定第四个元素不存在

由于您的示例iterate构造生成了递增序列,因此如果要将结果限制为小于100的元素,则可以使用take-while。例如:

(take-while #(< % 100) (iterate #(+ % 17) 0))