functional programming - Dealing with database reads in Clojure -
i trying 'purify' of clojure functions. point side-effecting code explicitly declared in 1 function. it's easy data @ start , write db @ end , have pure function transforming in between. however, usual situation transformation function requires db read somewhere in middle of logic:
(defn transform-users [users] (let [ids (map :id users) profiles (db/read :profiles ids)] (profiles->something profiles))) (->> (db/read :users) (transform-users) (db/write :something)
obviously simple example point is, how side-effecting db/read
function out of there, how can make transform-users
pure (and benefit, testable)?
one thing here dependency-injection-like approach of supplying (potentially) side-effectful function optional parameter, e.g.:
(defn transform-users [users & {:keys [ids->profiles] :or {ids->profiles #(db/read :profiles %)}] (let [ids (map :id users) profiles (ids->profiles ids)] (profiles->something profiles)))
this should testable since can mock injected functions without lot of effort. , bonus, supplying default value, you're documenting you're expecting , making function convenient call.
Comments
Post a Comment