Link to map versus map for refs versus multiple refs

I am working on a GUI in Swing + Clojure that requires various mutable pieces of data (e.g. scroll position, user data, file name, selected tool options, etc.).

I see at least three different ways to process this dataset:

Create a link to the map of all data:

(def data (ref { :filename "filename.xml" :scroll [0 0] })) 

Create a link map for individual data elements:

 (def datamap { :filename (ref "filename.xml") :scroll (ref [0 0]) })) 

Create a separate ref for each in the namespace:

 (def scroll (ref [0 0])) (def filename (ref "filename.xml")) 

Note. This data will be available at the same time, for example. background processing threads or a Swing event processing thread. However, there is probably no need for consistent transactional updates of several items.

What will be your recommended approach and why?

+4
source share
2 answers

First, if you end up using only one piece of a volatile state or several independent parts (regardless of how โ€œit makes no sense to ask if it is consistent with anotherโ€), why not go with Atoms and not with Ref ? This is a pretty significant reduction in overhead, which can make a difference if you make a lot of updates.

Secondly, saving the file name, scroll position, etc. in separate Refs (but not in Atoms) it is great if you carefully design your transactions (i.e. you need to mention all the relevant Refs, maybe some of them should be ensure d, etc. .. - basically the transaction should be fail if an inconsistent state occurs). Carefully designing such transactions can be a waste of effort if you manage the state of the GUI, most of which almost never change (besides the scroll position and the contents of the buffer, which can actually change often?) I mean, something is serious , since the answer should determine the final design). There are any number of scripts in which there are several objects of a reference type, preferably one, Iโ€™m just not sure if one of them is to control the basic state of the GUI .:-)

Note that updating nested structures stored in objects of a reference type is very clean in Clojure, for example. (using Atom):

 ;; assuming that state-o-matic is an Atom which holds a map, ;; which holds the key of :foo, with which a vector is associated, ;; whose first item is another vector, whose first item is a map ;; which holds the key of :bar associated to a number, ;; the following increments said number (swap! state-o-matic update-in [:foo 0 1 :bar] inc) 

See also get-in and assoc-in .

+6
source

If there is no concurrency - then there is no difference, you know.

But if it can be used from different threads, then the first case will be better. Because it guarantees you a consistent state.

+1
source

Source: https://habr.com/ru/post/1313021/


All Articles