I'm very new in Clojure. I'm learning with help from Clojure Koans. I found an answer with code below:
(= ["Real Jerry" "Bizarro Jerry"]
(do
(dosync
(ref-set the-world {})
(alter the-world assoc :jerry "Real Jerry")
(alter bizarro-world assoc :jerry "Bizarro Jerry")
(vec (map #(:jerry @%) [the-world bizarro-world]))))))
from: https://github.com/viebel/clojure-koans/blob/master/src/koans/16_refs.clj#L42
It's pretty unfriendly for Google to search like "Clojure @%". So I get nothing from Internet.
How does it works for the function "#(:jerry @%)"?
And the code below is the answer from me, but it doesn't work.
(= ["Real Jerry" "Bizarro Jerry"]
(do
(dosync
(ref-set the-world {})
(alter the-world assoc :jerry "Real Jerry")
(alter bizarro-world assoc :jerry "Bizarro Jerry")
(vec (map (fn [x] (:jerry x)) [the-world bizarro-world]))
)))
#( ...) is a reader macro for anonymous function where % means the first argument passed to the function. For example:
#(println %)
is equivalent to:
(fn [x] (println x))
@ is a reader macro for deref so again:
@some-variable
is the same as:
(deref some-variable)
and is used to dereference a current value from one of the ref types.
Thus #(:jerry @%) is an anonymous function which when applied to a ref (e.g. an atom) will deref its current value and use it as an argument to call :jerry keyword as a function with the value.
the-world and bizarro-world are "derefable", which means that you can use @ in front to get their value.
You are using an anonymous function, indicated by #( ). In an anonymous function, the percent sign % indicates the argument to the function.
So @% means, "dereference the argument to this function."
:jerry is a keyword used as a function, which gets the value associated with the key :jerry in the map.
For example:
(def coll [(ref {:jerry 21})
(ref {:jerry 42})])
=> #'user/coll
(map #(:jerry @%) coll)
=> (21 42)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With