On Jan 16, 7:33 pm, Laurent PETIT <[email protected]> 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 [email protected]
Note that posts from new members are moderated - please be patient with your
first post.
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en