Why doesn't the atom change?
(defn table-rows [data]
(def rows (atom [:tr]))
(map #(swap! rows conj [:td {:name %}]) data)
@rows)
(table-rows [{:name "foo"} {:name "bar"}])
evaluating table-rows as shown produces:
=> [:tr]
Why is this?
It doesn't change because map
is lazy and the result is never used/realized.
Apart from this the entire approach to this code snippet is wrong. Never declare a def
inside another def/defn
. Use let
instead. If you want to transform every element in a sequence map
is the correct function to use, but skip the atom. ->>
can help to make things more readable too.
(defn table-rows [data]
(->> data
(map (fn [{:keys [name] :as row}]
[:td {:name name}]))
(into [:tr])))
(table-rows [{:name "foo"} {:name "bar"}])
As a general rule for local variable use let
, never def
.
(defn table-rows [data]
(let [rows (for [row data]
[:td (:name row)])]
(into [:tr] rows)))