On Jan 16, 7:33 pm, Laurent PETIT <laurent.pe...@gmail.com> wrote:
> For the non lazy version , maybe using clojure.zip would help not blow
> up the stack ?
>
> (using clojure.zip/zip + a loop with recur on clojure.zip/next) ?

I've just tried it and it appears to be equivalent to the lazy walk
version, which I think is fully lazy after all (not tested, see
below).

(defn lazy-recursive-string-walk-with-zipper [f form]
  (loop [loc (z/seq-zip form)]
    (if (z/end? loc)
      (z/root loc)
      (recur (z/next
               (if (string? (z/node loc))
                 (zip/replace loc (f (z/node loc)))
                 loc))))))

The thing is, I should learn to read stack traces more carefully! The
StackOverflowError was coming from my test function.

(def pit (iterate list "bottom!"))

(defn test-walk [walker shallowest deepest]
  (doseq [depth (range shallowest deepest)]
    (pprint (walker #(str depth " reached " %)
              (last (take depth pit))))))

It's the iterate function that was throwing the error, while used
directly it can generate a 1000 lists deep nested list, but when used
in the test-walk function it only reach 828. The stack overflow make
more sense now, yet the stack trace is not easy to decipher.

No message.
  [Thrown class java.lang.StackOverflowError]

Restarts:
 0: [ABORT] Return to SLIME's top level.

Backtrace:
  0: clojure.lang.PersistentHashMap$BitmapIndexedNode.index
(PersistentHashMap.java:467)
  1: clojure.lang.PersistentHashMap$BitmapIndexedNode.assoc
(PersistentHashMap.java:616)
  2: clojure.lang.PersistentHashMap$TransientHashMap.doAssoc
(PersistentHashMap.java:222)
  3: clojure.lang.ATransientMap.assoc(ATransientMap.java:64)
  4: clojure.lang.PersistentHashMap.create(PersistentHashMap.java:79)
  5: clojure.core$hash_map__4297.doInvoke(core.clj:279)
  6: clojure.lang.RestFn.invoke(RestFn.java:426)
  7: clojure.core$print_sequential__6823.invoke(core_print.clj:37)
  8: clojure.core$fn__6908.invoke(core_print.clj:136)
  9: clojure.lang.MultiFn.invoke(MultiFn.java:161)
 10: clojure.core$pr_on__5416.invoke(core.clj:2336)
 11: clojure.core$print_sequential__6823.invoke(core_print.clj:54)
 12: clojure.core$fn__6908.invoke(core_print.clj:136)
 13: clojure.lang.MultiFn.invoke(MultiFn.java:161)
 14: clojure.core$pr_on__5416.invoke(core.clj:2336)

I'll look a little deeper at this error and keep this post updated. In
the meantime, has anyone got an idea to replace iterate for creating
mock nested lists to test recursive-string-walk?

P.S.: Finally learned to use zippers and they can be very useful, like
that concept a lot. Found it intimidating at first but I've just read
an excellent write-up about them today:

http://scienceblogs.com/goodmath/2010/01/zippers_making_functional_upda.php?

Thanks

- budu
-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en

Reply via email to