Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make a more general atom wrapper? #16

Closed
Frozenlock opened this issue Jan 28, 2015 · 2 comments
Closed

Make a more general atom wrapper? #16

Frozenlock opened this issue Jan 28, 2015 · 2 comments

Comments

@Frozenlock
Copy link
Contributor

Following what I've written in reagent-project/reagent#76, I decided to explore how to make a more general atom wrapper.

If you have a browser repl active, you can run this code:
https://www.refheap.com/96603

After that, you can implement the classic cursor simply with:

(defn cur [a path]
  (entangle a
            #(get-in % path)
            #(swap! %1 assoc-in path %2)))

But you can also do some more fancy/complex operations, like this one:

(def a (atom {:first-name "Bob" :last-name "Moran" :age 35 :sex "M"}))
=> #<Atom: {:first-name "Bob", :last-name "Moran", :age 35, :sex "M"}>

;; now create a new atom with custom get/update functions
(def b (entangle a
                  (fn [s-a]
                    [(:first-name s-a) (:age s-a)])
                  (fn [s-a new-value]
                    (swap! s-a assoc
                           :first-name (first new-value)
                           :age (last new-value)))))
=> #<Atom(+): ["Bob" 35]>

;; now we modify this new atom
(reset! b ["Mike" 22])
=> ["Mike" 22]

b
=> #<Atom(+): ["Mike" 22]>

;; reflected in the source atom:
a
=> #<Atom: {:first-name "Mike", :last-name "Moran", :age 22, :sex "M"}>

Notice how the same data can be present in two very different structure.

We also have much finer control of what is allowed when we update the source-atom. In this example, only the :first-name and :age fields will be modified. :last-name and :sex can't be seen (let alone modified) from the new atom.

Does anyone think it's worth exploring?

@seancorfield
Copy link
Member

Looks interesting. Does it cater for all of the protocol methods "doing the right thing"? Or would that depend on just how elaborate your new getter / updater functions were?

Also, we need to decide whether cursors are part of core or standalone going forward. If the former, some of your earlier tweaks need to get added to core, rather than adding more generic stuff to the standalone library.

With this approach I can definitely see the benefit of a Clojure version!

@Frozenlock
Copy link
Contributor Author

I implemented something a little more complete in another project.
I was afraid this was stretching cursors a little too far. (In my mind cursors are get-in assoc-in with a path.)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants