This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2022-06-02
Channels
- # announcements (34)
- # babashka (19)
- # beginners (106)
- # calva (50)
- # cider (25)
- # clj-commons (39)
- # clj-kondo (16)
- # clojure (59)
- # clojure-czech (3)
- # clojure-europe (33)
- # clojure-norway (9)
- # clojure-seattle (1)
- # clojure-sweden (1)
- # clojure-uk (2)
- # clojured (28)
- # clojuredesign-podcast (1)
- # clojurescript (7)
- # code-reviews (19)
- # conjure (15)
- # cursive (3)
- # datomic (3)
- # emacs (21)
- # etaoin (28)
- # graphql (4)
- # introduce-yourself (1)
- # joyride (2)
- # kaocha (2)
- # london-clojurians (8)
- # lsp (24)
- # music (4)
- # nbb (4)
- # nextjournal (1)
- # off-topic (13)
- # other-languages (16)
- # remote-jobs (1)
- # rewrite-clj (6)
- # sci (1)
- # shadow-cljs (40)
- # tools-deps (15)
am looking for a CLJC suite of ordered collections but it seems like https://github.com/clj-commons/ordered is just for the JVM. Is that right? Do any of the crew know of a CLJS equivalent (cos my search fu is letting me down today ! )
(defn record-state-change
"Add updated-item to the current state under the change-id key.
If the change-id does not exist, add it to a FIFO list of changes."
[{:keys [changelog] :as state} updated-item change-id]
(cond-> state
(not (get state change-id)) (assoc state :changelog
(vec (conj changelog change-id)))
:always (assoc change-id updated-item)))
Maybe I am more optimistic about the quality of libs from the Clojure community than I am about JS but still, fewer deps are better indeed
Instead of (cond-> state ...)
I'd write here
(cond-> (assoc change-id updated-item) (not (get state change-id)) ...)
@U04V5V0V4 but wait, how is your example an ordered set? It's an ordered map, essentially?
the map is unordered, as usual but the changelog list is ordered by insertion and avoids duplicate insertion.
Another way to do this is to have an extra key: inserted-at ...
with some timestamp or incrementing value so you can sort the map entries based on that
the change-id is of the form id/digest and the digest is based on some input text. If that changes we will get a new digest and a new compound ID
(ns replacement.protocol.state
(:require [replacement.protocol.hashing :as hashing]
#?(:cljs [promesa.core :as p])))
(defn record-state-change
"Add updated-item to the current state under the change-id key.
If the change-id does not exist, add it to a LIFO list of changes."
[{:keys [changelog] :as state} updated-item change-id]
(cond-> state
(not (get state change-id)) (assoc :changelog (vec (cons change-id changelog)))
:always (assoc change-id updated-item)))
(defn update-state
[state updated-item distinction-key form-id]
(let [digest-input (get updated-item distinction-key)]
#?(:clj (let [digest (hashing/digest digest-input)]
(record-state-change state updated-item (keyword form-id digest)))
:cljs (p/let [digest (hashing/digest digest-input)]
(record-state-change state updated-item (keyword form-id digest))))))
I don't know how often the order will be queried ... maybe never but at least once when I demo it 😉
the thing I'm trying to leverage is that s/conform
will produce data that only changes if there is a meangingful change in the code text. Then I can keep a history of those changes and perform structural diffs.
I'm not getting into all the edge cases around that but I think it will be interesting to see how far we can go with that data
btw. for LIFO I usually use seq + conj for insertions + peek/pop for takes. That way allows you to not convert data from seq to vector and back on each insertion