Skip to content

Instantly share code, notes, and snippets.

@cgrand
Last active August 29, 2015 14:03
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save cgrand/be2818e997d1c5d13010 to your computer and use it in GitHub Desktop.
Save cgrand/be2818e997d1c5d13010 to your computer and use it in GitHub Desktop.
;; You are right that the f function passed to update gets called only once.
;; However the value passed to it may be composite.
;; multifocals
=> (defn swap [[a b]] [b a])
#'enliven.core.lenses/swap
=> (update {:a "A" :b "B" :c "C"}
(juxt :a :b) swap)
{:a "B", :b "A", :c "C"}
;; Lenses such as the ones created by lens-map or juxt (see below) are what I call multifocals:
;; the focused value is a composite of each member lens focus.
;; So it somehow gathers reads and scatters writes.
;; (tangentially related: see also focus and autofocus (af) functions which wrap a function
;; in lenses (most of them being read-only))
;; Implicit iteration (à la fmap-based lens) didn't seem sensible to me in this design.
;; If you want to iterate you focus on the collection and iterate in user code (eg the function
;; passed to update or even by having discrete fetch and putback calls). The same goes for Maybe
;; handling.
;; juxt, from a local branch:
(defn juxt ; TODO make safe version w/ dependent lenses
"Beware of dependent lenses!"
[& lenses]
(let [lenses (vec lenses)]
(reify Lens
(-fetch [_ x]
(mapv #(fetch x %) lenses))
(-putback [_ x y]
(reduce-kv (fn [x idx l]
(putback x l (nth y idx)))
x lenses)))))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment