1

Why the last expression retruns

{:a :foo, :args [{:id :XX}], :id :XX}

instead of:

{:a :foo, :args [], :id :XX}

(require '[clojure.zip :as zip])

(defn my-zipper [tree]
  (zip/zipper
    (fn branch? [node]
      (:args node))
    (fn children [node]
      (:args node))
    (fn make-node [node children]
      (assoc node :args (vec children)))
    tree))

(def z (my-zipper {:a :foo :args []}))

(loop [loc z]
  (if (zip/end? loc)
    (zip/node loc)
    (recur
      (zip/next 
         (zip/edit loc #(assoc % :id :XX))))))

It looks like the problem is associated with the fact that traversing with zip/next reveals there are 2 nodes :

(zip/node (zip/next z))             ;  => nil
(zip/node (zip/next (zip/next z)))  ;  => {:a :foo :args []} 

Why is that? There is a single node with empty children so there should be only one node, correct?

Lambder
  • 2,953
  • 1
  • 26
  • 20

1 Answers1

2

After looking at the code of clojure.zip/vector-zip I conclude that lack of node's children should be communicated with nil. The empty sequence doesn't work. So the children function should really be:

(fn children [node]
      (seq (:args node)))
Lambder
  • 2,953
  • 1
  • 26
  • 20