首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >lazy-seq -- cons or or in

lazy-seq -- cons or or in
EN

Stack Overflow用户
提问于 2013-06-10 01:28:05
回答 2查看 417关注 0票数 8

cons应该在里面吗(lazy-seq...)

代码语言:javascript
复制
(def lseq-in (lazy-seq (cons 1 (more-one))))

还是出去?

代码语言:javascript
复制
(def lseq-out (cons 1 (lazy-seq (more-one))))

我注意到了

代码语言:javascript
复制
(realized? lseq-in)
        ;;; ⇒ false

(realized? lseq-out)
        ;;; ⇒ <err>
        ;;;   ClassCastException clojure.lang.Cons cannot be cast to clojure.lang.IPending  clojure.core/realized? (core.clj:6773)

clojuredocs.org上的所有示例都使用"out“。

涉及的权衡是什么?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-06-10 04:14:50

您肯定希望(lazy-seq (cons ...))作为您的默认设置,只有在您有明确的理由时才会偏离。clojuredocs.org很好,但示例都是社区提供的,我不会称它们为“文档”。当然,它的构建方式的一个后果是,这些示例往往是由刚刚学会如何使用所讨论的构造并希望提供帮助的人编写的,所以他们中的许多人都很差。我会参考clojure.core中的代码,或者其他已知良好的代码。

为什么这应该是默认的?考虑map的这两个实现

代码语言:javascript
复制
(defn map1 [f coll]
  (when-let [s (seq coll)]
    (cons (f (first s))
          (lazy-seq (map1 f (rest coll))))))

(defn map2 [f coll]
  (lazy-seq
    (when-let [s (seq coll)]
      (cons (f (first s))
            (map2 f (rest coll))))))

如果调用(map1 prn xs),那么将立即实现并打印xs的元素,即使您从未有意实现所得到的映射序列的元素。另一方面,map2会立即返回一个惰性序列,延迟其所有工作,直到请求一个元素。

票数 8
EN

Stack Overflow用户

发布于 2013-06-10 04:14:21

lazy-seq中使用cons时,seq的第一个元素的表达式的求值会被延迟;而在cons中,表达式的计算会立即完成,并且只会延迟seq的"rest“部分的构造。(所以(rest lseq-out)将是一个懒惰的序列。)

因此,如果计算第一个元素的成本很高,而且可能根本不需要它,那么将cons放在lazy-seq中更有意义。如果将初始元素作为参数提供给lazy seq生成器,那么在外部使用cons可能更有意义(clojure.core/iterate就是这种情况)。否则,这不会有太大的不同。(在开始时创建惰性seq对象的开销可以忽略不计。)

Clojure本身使用这两种方法(尽管在大多数情况下,lazy-seq包装了整个seq生成表达式,不一定以cons开头)。

票数 7
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/17012266

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档