### 列表推导式
宏 `for` 和 `doseq` 可以用来做list comprehension. 它们支持遍历多个集合 (最右边的最快) ,同时还可以做一些过滤用 `:when 和` `:while。` 宏 `for` 只接受一个表达式 , 它返回一个懒惰集合作为结果. 宏 `doseq` 接受任意数量的表达式, 以有副作用的方式执行它们, 并且返回 `nil` .
下面的例子会打印一个矩阵里面 所有的元素出来。 它们会跳过 “B” 列 并且只输出小于3的那些行。我们会在“序列”那一节介绍 `dorun` , 它会强制提取 for 所返回的懒惰集合.
```
(def cols "ABCD")
(def rows (range 1 4)) ; purposely larger than needed to demonstrate :while
(println "for demo")
(dorun
(for [col cols :when (not= col \B)
row rows :while (< row 3)]
(println (str col row))))
(println "\ndoseq demo")
(doseq [col cols :when (not= col \B)
row rows :while (< row 3)]
(println (str col row)))
```
上面的代码的输出是这样的:
```
for demo
A1
A2
C1
C2
D1
D2
doseq demo
A1
A2
C1
C2
D1
D2
```
宏 `loop` 是一个special form, 从它的名字你就可以猜出来它是用来遍历的. 它以及和它类似的 `recur` 会在下一节介绍.