0Pricing
Clojure Functional Programming & JVM Backend Development · 课时

惰性序列与无限流

掌握 Clojure 的惰性序列,用它们表示无限流、延迟计算,并在不耗尽内存的情况下高效处理数据。

惰性序列与无限流 是 CoddyKit 上的免费 Clojure Functional Programming & JVM Backend Development 课时。 这是第 4 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 Clojure Functional Programming & JVM Backend Development 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 Clojure Functional Programming & JVM Backend Development 课程共包含 4 节课。

本课时的部分内容尚未翻译,以英文显示。

What Is Laziness?

A lazy sequence computes its elements only as they are needed. This lets you describe potentially infinite data and consume just the part you want.

An Infinite Range

range with no arguments returns an infinite lazy sequence. It never materializes fully; you take only what you need.

(take 5 (range))
; => (0 1 2 3 4)

iterate

iterate builds an infinite sequence by repeatedly applying a function to a starting value.

(take 5 (iterate (fn [x] (* x 2)) 1))
; => (1 2 4 8 16)

repeat and cycle

repeat yields the same value forever; cycle loops a collection forever. Both are lazy.

(take 3 (repeat :x))   ; => (:x :x :x)
(take 5 (cycle [1 2])) ; => (1 2 1 2 1)

lazy-seq

You build your own lazy sequences with lazy-seq. The body runs only when the next element is requested.

(defn nums-from [n]
  (lazy-seq
    (cons n (nums-from (inc n)))))

(take 4 (nums-from 10)) ; => (10 11 12 13)

Lazy Transformations

map, filter, and take-while are all lazy. Chaining them does no work until you consume the result.

(->> (range)
     (map (fn [x] (* x x)))
     (filter even?)
     (take 4))
; => (0 4 16 36)

Realization & Chunking

Lazy seqs are realized in chunks of 32 for efficiency. So asking for one element may compute up to 32. Keep transformations side-effect-free to avoid surprises.

(first (map (fn [x] (println "seen" x) x) (range 100)))
; prints 0..31 due to chunking

Forcing Realization

Use doall to fully realize a lazy sequence (e.g. to trigger side effects), or dorun when you do not need the results.

(doall (map println [1 2 3]))

Avoiding the Head-Holding Trap

If you keep a reference to the head of an infinite seq while walking it, the whole realized portion stays in memory. Let go of the head to allow garbage collection.

; Bad: binding holds the head
(let [s (range)] (last (take 1000000 s)))

Practical Stream: Fibonacci

Lazy sequences elegantly express recursive streams like Fibonacci numbers.

(def fibs
  (map first
    (iterate (fn [[a b]] [b (+ a b)]) [0 1])))

(take 7 fibs) ; => (0 1 1 2 3 5 8)

Laziness vs Transducers

Lazy seqs build intermediate sequences; transducers (from a prior lesson) avoid them. Use laziness for infinite/streamed data and transducers for high-throughput pipelines.

Quick Check

Test your lazy-sequence intuition.

Recap

You learned how lazy sequences defer computation and model infinite streams.

  • Generate with range, iterate, repeat, cycle, lazy-seq
  • map/filter stay lazy until consumed
  • Beware chunking and head-holding

常见问题解答

「惰性序列与无限流」课时是免费的吗?

是的 — 「惰性序列与无限流」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Clojure Functional Programming & JVM Backend Development 课程的其余内容,请升级到 CoddyKit PRO。 Clojure Functional Programming & JVM Backend Development 课程共包含 4 节课。

「惰性序列与无限流」这节课中我会学到什么?

掌握 Clojure 的惰性序列,用它们表示无限流、延迟计算,并在不耗尽内存的情况下高效处理数据。 你通过在浏览器中直接运行的动手代码来练习 Clojure Functional Programming & JVM Backend Development,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 Clojure Functional Programming & JVM Backend Development 需要有经验吗?

无需任何先前经验。CoddyKit 上的 Clojure Functional Programming & JVM Backend Development 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 4 节课,共 4 节。

「惰性序列与无限流」课时需要多长时间?

大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。

我能在这节 Clojure Functional Programming & JVM Backend Development 课中编写并运行代码吗?

能。每节 Clojure Functional Programming & JVM Backend Development 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。

此课程中的所有课时

  1. 使用转换器实现高效处理
  2. 单子与函数式抽象
  3. 使用 clojure.test.check 进行基于属性的测试
  4. 惰性序列与无限流
← 返回 Clojure Functional Programming & JVM Backend Development