Part 1.
I know that the API is trying to hit the sweet spot on the brevity vs.
information curve, but there are several areas where more information
is needed; one of these is clojure.walk.
Let's say that I have some nested set of vectors:
(def nestV [ [0 [0] ] [0 0] ])
and I want to apply
#(+ % 3)
to each element and get out a nested set of vectors with the same
shape as nestV
[ [3 [3] ] [3 3]].
The overview to clojure.walk says the following: "It takes any data
structure (list, vector, map, set, seq), calls a function on every
element, and uses the return value of the function in place of the
original." This sounds like I will find a function within this
namespace that will do what I want. I tried prewalk and postwalk,
which, from the their usage "examples" would appear to be what I want.
But when I try to test them I find the following:
user=> (prewalk #(+ 3 %) nestV)
#<CompilerException java.lang.ClassCastException:
clojure.lang.PersistentVector (NO_SOURCE_FILE:0)>
user=> (postwalk #(+ 3 %) nestV)
#<CompilerException java.lang.RuntimeException:
java.lang.ClassCastException: clojure.lang.PersistentVector
(NO_SOURCE_FILE:0)>
The problem with the usage "examples" is that they don't actually show
what the outcome will be. Further, there is no documentation other
than the API on clojure.walk.
Part 2
Is there a function in the API that allows me to do the type of
calculation I described above?
user=> (some-function #(+ % 3) nestV)
(((3(3))(3 3))
> --
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clo...@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+u...@googlegroups.com
> For more options, visit this group at
> http://groups.google.com/group/clojure?hl=en
>
> To unsubscribe from this group, send email to clojure+unsubscribegooglegroups.com or reply to this email with the words "REMOVE ME" as the subject.
>
--
And what is good, Phaedrus,
And what is not good—
Need we ask anyone to tell us these things?
Ok here is what I get:
(prewalk #(doto % prn) [[3 [3]] [3 3]])
[[3 [3]] [3 3]]
[3 [3]]
3
[3]
3
[3 3]
3
3
[[3 [3]] [3 3]]
Thus, it appears that an "element" of my nested vectors isn't just the
values within the vectors, but also stands for the inner vectors as
well. I agree that this is a (maybe THE) proper way of reading the
quoted API text from my earlier post. But this goes to the first part
of my earlier post, given this small example I have a much better idea
of what is going on.
I have a workaround/solution for you. I still don't know exactly
why, but the :else clause in walk calls outer on form. This will give
you all sorts of class cast exceptions if you only wanted to apply the
function to each element individually. With that said, just wrap your
function with another that ignores any sequential structures.
(defn ignore-sequential [f]
#(if (sequential? %) % (f %)))
user> (prewalk (ignore-sequential inc) [1 [2] 3])
[2 [3] 4]
user> (postwalk (ignore-sequential inc) [1 [2] 3])
[2 [3] 4]
-SS