2024 年 Clojure 状态调查! 分享您的想法。

欢迎!请参阅 关于 页面以了解此工作方式的相关更多信息。

+2
序列
重新标记

sequence 的文档字符串说明

  • "... 不会强制惰性序列..."
  • "... 返回一个惰性序列..."

基于此,我并不期望 sequence (凭自身)会消耗任何输入。不确定这是否是预期的行为,但也许措辞可以调整以表明 sequence 将部分实现其输入。

(do
  (->> (range 1000)
       (map #(doto % prn))
       (sequence (map inc)))
  nil)

打印以下内容到标准输出

0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31

这与惰性序列函数如 mapfilter 以及延迟选项如 eduction 形成对比。以下表达式不会打印任何内容到标准输出

(do
  (->> (range 1000)
       (map #(doto % prn))
       (eduction (map inc)))
  nil)

(do
  (->> (range 1000)
       (map #(doto % prn))
       (map inc))
  nil)

另一个似乎也表明 sequence (凭自身)不会消耗任何输入的参考资料,https://clojure.org/reference/transducers#_sequence

生成的序列元素是逐步计算的。
这些序列将根据需要逐步消耗输入,并完全实现中间操作。这种行为与惰性序列上的等效操作不同。
(着重标注)
这不是很奇怪,sequence 可以分块,但使我惊讶的是,sequence 会在没有任何返回结果额外调用的前提下部分实现其输入。

(着重标注)

这不是很奇怪,sequence 可以分块,但令我惊讶的是,sequence 在无需任何额外的返回结果调用的前提下就部分实现了其输入。

2 个答案

+2

selected
 
最佳答案

当使用sequence的转接过载函数时,它会在N个源上创建一个转化迭代器(sequence是唯一可以访问这一特性的函数)。然后通过RT.chunkIteratorSeq()将其包装成seq - 这是强制第一个元素确定是否需要返回nil或序列的方法。

没有回顾旧笔记,我不记得是否是我们考虑后认为不重要的事项,还是遗漏了应该改正的事项。我同意你的看法,行为似乎与文档字符串矛盾。

可能已经有了相关的工单,我还没去看。

+2
...