clojurescript - Clojure newbie struggling with protocols -



clojurescript - Clojure newbie struggling with protocols -

i attempting build out concept of cursor in clojurescript, backed atom. cursor recursive zipper mechanism editing immutable nested associated datastructure.

i newbie @ clojure, can help me spot errors?

(defprotocol cursor (refine [this path]) (set [this value]) (value [this])) (defn- build-cursor* [state-atom paths] (reify cursor (set [this value] (swap! state-atom (assoc-in @state-atom paths value))) (refine [this path] (build-cursor* state-atom (conj paths path))) (value [this] (get-in @state-atom paths)))) (defn build-cursor [state-atom] (build-cursor* state-atom [])) (comment (def s (atom {:a 42})) (def c (build-cursor s)) (assert (= (value c) {:a 42})) (set c {:a 43}) ;; warning: wrong number of args (2) passed quiescent-json-editor.core/set @ line 1 <cljs repl> (assert (= (value c) {:a 43})) (def ca (refine c :a)) ;; warning: wrong number of args (2) passed quiescent-json-editor.core/refine @ line 1 <cljs repl> (assert (= (value ca) 43)) (set ca 44) (assert (= (value ca) 43)) )

i new clojure well, took stab @ , found 2 issues.

first, set method clashes core library function (even though it's in cursor protocol). sake of debugging, added underscore prefixes avoid this.

second, seems calling _set on root cursor corrupts value. found assoc-in not handle empty path [] way might expect:

(assoc-in {} [] {:a 7}) ; {nil {:a 7}}

...so that's reason cond in _set.

here test code:

(ns cursory) (defprotocol cursor (_path [this]) (_root [this]) (_refine [this path]) (_set [this value]) (_value [this])) (defn- build-cursor* [state-atom paths] (reify cursor (_path [this] paths) (_root [this] @state-atom) (_set [this value] (cond (empty? paths) (reset! state-atom value) :else (assoc-in @state-atom paths value))) (_refine [this path] (build-cursor* state-atom (conj paths path))) (_value [this] (get-in @state-atom paths)))) (defn build-cursor [state-atom] (build-cursor* state-atom [])) (comment (def s (atom {:a 42, :b 84})) (def c (build-cursor s)) (_set c {:a 44, :b 88}) (_root c) (_path c) (_value c) (def ca (_refine c :a)) (_path ca) (_value ca) (_set ca 42) (get-in {:a 1 :b 2} []) (assoc-in {} [:a :b] 7) (assoc-in {} [] {:a 7}) (empty? []) )

clojure clojurescript

Comments

Popular posts from this blog

php - Edges appear in image after resizing -

ios8 - iOS custom keyboard - preserve state between appearances -

Delphi change the assembly code of a running process -