I am new to clojure, and am learning by recreating the cd project from Practical Common Lisp. I am having troubles implementing the update function using a where 'clause' selector. Executing (update (where :artist "AC/DC") :rating 10) results in my database getting blown away, and just an empty list returned. Here is my code:
(defn where [& {:keys [title artist genre rating]}] (fn [cd] (and (if title (= (get cd :title) title) true) (if artist (= (get cd :artist) artist) true) (if genre (= (get cd :genre) genre) true) (if rating (= (get cd :rating) rating) true)))) (defn update [selector-fn & {:keys [title artist genre rating]}] (def ^:dynamic *db* (map (fn [row] (when (apply selector-fn row) (if title (def row (assoc-in row [:title] title))) (if artist (def row (assoc-in row [:artist] artist))) (if genre (def row (assoc-in row [:genre] genre))) (if rating (def row (assoc-in row [:rating] rating)))) row) *db*))) I've implemented each CD as a hash-map:
(defn make-cd [title artist genre rating] {:title title :artist artist :genre genre :rating rating }) So am thinking that my use of assoc-in is correct. Any ideas on what I am doing wrong would be greatly appreciated.
thanks...
MZ
Ok. Based on Arthur's comments here is what I have for the update function now:
(defn update [selector-fn & {:keys [title artist genre rating]}] (map (fn [row] (when (apply selector-fn row) (-> row (#(if title (assoc-in % [:title] title) %)) (#(if artist (assoc-in % [:artist] artist) %)) (#(if genre (assoc-in % [:genre] genre) %)) (#(if rating (assoc-in % [:rating] rating) %))))) *db*)) I think I still need the map form as I need to iterate over *db*. I don't want to change the rating for all the CD's in *db* just the ones where artist is AC/DC. so map will iterate over each cd (binding it to row), then call the where function to see if the title matches. If so, then it will return true allowing the rating to be updated.
Unfortunately this still doesn't work.
ArityException Wrong number of args (4) passed to: core$where$fn clojure.lang.AFn.throwArity (AFn.java:437)