经典著作The Little Lisper ( The Little Schemer ) 建立在两大理念之上
- 您可以以递归方式解决大多数问题(而不是使用循环)(假设您有尾调用优化)
- Lisp 很棒,因为它本身很容易实现。
现在有人可能认为这适用于所有 Lispy 语言(包括 Clojure)。问题是,这本书是当时(1989 年)的产物,可能在我们今天所拥有的高阶函数 (HOF) 函数式编程之前。(或者至少被认为适合本科生)。
递归的好处(至少部分)是易于遍历嵌套数据结构,如('a 'b ('c ('d 'e)))
.
例如:_
(def leftmost
(fn [l]
(println "(leftmost " l)
(println (non-atom? l))
(cond
(null? l) '()
(non-atom? (first l)) (leftmost (first l))
true (first l))))
现在有了功能拉链——我们有一种遍历嵌套数据结构的非递归方法,并且可以像遍历任何惰性数据结构一样遍历它们。例如:_
(defn map-zipper [m]
(zip/zipper
(fn [x] (or (map? x) (map? (nth x 1))))
(fn [x] (seq (if (map? x) x (nth x 1))))
(fn [x children]
(if (map? x)
(into {} children)
(assoc x 1 (into {} children))))
m))
(def m {:a 3 :b {:x true :y false} :c 4})
(-> (map-zipper m) zip/down zip/right zip/node)
;;=> [:b {:y false, :x true}]
现在看来,您可以使用以下任一方法解决任何嵌套列表遍历问题:
- a
zipper
如上,或 - a
zipper
遍历结构并返回一组键,可让您使用assoc
.
假设:
- 我当然假设数据结构是固定大小的,并且在遍历之前完全知道
- 我不包括流数据源方案。
我的问题是:由于拉链和 HOF,递归是一种气味(在惯用的 Clojure 中)吗?