clean up terminology – defpath -> defnav, path -> nav, fixed-pathed-path -> fixed-pathed-nav, variable-pathed-path -> variable-pathed-nav, StructurePath -> Navigator (breaking changes)

This commit is contained in:
Nathan Marz 2016-05-21 15:54:07 -04:00
parent c567045fb5
commit cdcdbbbaa4
6 changed files with 92 additions and 93 deletions

View file

@ -3,20 +3,20 @@
[com.rpl.specter.macros
:refer
[pathed-collector
variable-pathed-path
fixed-pathed-path
variable-pathed-nav
fixed-pathed-nav
defcollector
defpath
defnav
defpathedfn
]]
)
(:use [com.rpl.specter.protocols :only [StructurePath]]
(:use [com.rpl.specter.protocols :only [Navigator]]
#+clj [com.rpl.specter.macros :only
[pathed-collector
variable-pathed-path
fixed-pathed-path
variable-pathed-nav
fixed-pathed-nav
defcollector
defpath
defnav
defpathedfn]]
)
(:require [com.rpl.specter.impl :as i]
@ -119,7 +119,7 @@
(defn replace-in
"Similar to transform, except returns a pair of [transformed-structure sequence-of-user-ret].
The transform-fn in this case is expected to return [ret user-ret]. ret is
The transform-fn in this case is expected to return [ret user-ret]. ret is
what's used to transform the data structure, while user-ret will be added to the user-ret sequence
in the final return. replace-in is useful for situations where you need to know the specific values
of what was transformed in the data structure."
@ -151,7 +151,7 @@
;; Built-in pathing and context operations
(defpath
(defnav
^{:doc "Stops navigation at this point. For selection returns nothing and for
transformation returns the structure unchanged"}
STOP
@ -162,7 +162,7 @@
structure
))
(defpath
(defnav
^{:doc "Stays navigated at the current point. Essentially a no-op navigator."}
STAY
[]
@ -171,15 +171,15 @@
(transform* [this structure next-fn]
(next-fn structure)))
(def ALL (comp-paths (i/->AllStructurePath)))
(def ALL (comp-paths (i/->AllNavigator)))
(def VAL (i/->ValCollect))
(def LAST (comp-paths (i/->PosStructurePath last i/set-last)))
(def LAST (comp-paths (i/->PosNavigator last i/set-last)))
(def FIRST (comp-paths (i/->PosStructurePath first i/set-first)))
(def FIRST (comp-paths (i/->PosNavigator first i/set-first)))
(defpath
(defnav
^{:doc "Uses start-fn and end-fn to determine the bounds of the subsequence
to select when navigating. Each function takes in the structure as input."}
srange-dynamic
@ -190,7 +190,7 @@
(i/srange-transform structure (start-fn structure) (end-fn structure) next-fn)
))
(defpath
(defnav
^{:doc "Navigates to the subsequence bound by the indexes start (inclusive)
and end (exclusive)"}
srange
@ -205,7 +205,7 @@
(def END (srange-dynamic count count))
(defpath
(defnav
^{:doc "Navigates to the specified subset (by taking an intersection).
In a transform, that subset in the original set is changed to the
new value of the subset."}
@ -221,7 +221,7 @@
(set/union newset))
)))
(defpath
(defnav
^{:doc "Navigates to the specified submap (using select-keys).
In a transform, that submap in the original map is changed to the new
value of the submap."}
@ -236,7 +236,7 @@
(merge (reduce dissoc structure m-keys)
newmap))))
(defpath
(defnav
walker
[afn]
(select* [this structure next-fn]
@ -244,7 +244,7 @@
(transform* [this structure next-fn]
(i/walk-until afn next-fn structure)))
(defpath
(defnav
codewalker
[afn]
(select* [this structure next-fn]
@ -260,7 +260,7 @@
children in the same order when executed on \"select\" and then
\"transform\"."
[& path]
(fixed-pathed-path [late path]
(fixed-pathed-nav [late path]
(select* [this structure next-fn]
(next-fn (compiled-select late structure)))
(transform* [this structure next-fn]
@ -273,7 +273,7 @@
next-val))
structure)))))
(defpath
(defnav
^{:doc "Navigates to the specified key, navigating to nil if it does not exist."}
keypath
[key]
@ -283,7 +283,7 @@
(assoc structure key (next-fn (get structure key)))
))
(defpath
(defnav
^{:doc "Navigates to the key only if it exists in the map."}
must
[k]
@ -296,7 +296,7 @@
structure
)))
(defpath
(defnav
^{:doc "Navigates to result of running `afn` on the currently navigated value."}
view
[afn]
@ -306,14 +306,14 @@
(next-fn (afn structure))
))
(defpath parser [parse-fn unparse-fn]
(defnav parser [parse-fn unparse-fn]
(select* [this structure next-fn]
(next-fn (parse-fn structure)))
(transform* [this structure next-fn]
(unparse-fn (next-fn (parse-fn structure)))
))
(defpath
(defnav
^{:doc "Navigates to atom value."}
ATOM
[]
@ -333,7 +333,7 @@
will be parameterized in the order of which the parameterized navigators
were declared."
[& path]
(fixed-pathed-path [late path]
(fixed-pathed-nav [late path]
(select* [this structure next-fn]
(i/filter-select
#(i/selected?* late %)
@ -346,7 +346,7 @@
next-fn))))
(defpathedfn not-selected? [& path]
(fixed-pathed-path [late path]
(fixed-pathed-nav [late path]
(select* [this structure next-fn]
(i/filter-select
#(i/not-selected?* late %)
@ -377,14 +377,14 @@
will be parameterized in the order of which the parameterized navigators
were declared."
[path update-fn]
(fixed-pathed-path [late path]
(fixed-pathed-nav [late path]
(select* [this structure next-fn]
(next-fn (compiled-transform late update-fn structure)))
(transform* [this structure next-fn]
(next-fn (compiled-transform late update-fn structure)))))
(extend-type #+clj clojure.lang.Keyword #+cljs cljs.core/Keyword
StructurePath
Navigator
(select* [kw structure next-fn]
(next-fn (get structure kw)))
(transform* [kw structure next-fn]
@ -392,14 +392,14 @@
))
(extend-type #+clj clojure.lang.AFn #+cljs function
StructurePath
Navigator
(select* [afn structure next-fn]
(i/filter-select afn structure next-fn))
(transform* [afn structure next-fn]
(i/filter-transform afn structure next-fn)))
(extend-type #+clj clojure.lang.PersistentHashSet #+cljs cljs.core/PersistentHashSet
StructurePath
Navigator
(select* [aset structure next-fn]
(i/filter-select aset structure next-fn))
(transform* [aset structure next-fn]
@ -412,7 +412,7 @@
i/pred*
)
(defpath
(defnav
^{:doc "Navigates to the provided val if the structure is nil. Otherwise it stays
navigated at the structure."}
nil->val
@ -462,7 +462,7 @@
will be parameterized in the order of which the parameterized navigators
were declared."
[& conds]
(variable-pathed-path [compiled-paths conds]
(variable-pathed-nav [compiled-paths conds]
(select* [this structure next-fn]
(if-let [selector (i/retrieve-cond-selector compiled-paths structure)]
(->> (compiled-select selector structure)
@ -484,7 +484,7 @@
"A path that branches on multiple paths. For updates,
applies updates to the paths in order."
[& paths]
(variable-pathed-path [compiled-paths paths]
(variable-pathed-nav [compiled-paths paths]
(select* [this structure next-fn]
(->> compiled-paths
(mapcat #(compiled-select % structure))

View file

@ -67,9 +67,9 @@
(apply transform-fn (conj vals structure))))))
))
(def StructurePathExecutor
(def LeanPathExecutor
(->ExecutorFunctions
:spath
:leanpath
(fn [params params-idx selector structure]
(selector structure (fn [structure] [structure])))
(fn [params params-idx transformer transform-fn structure]
@ -158,8 +158,8 @@
(defn structure-path-impl [this]
(if (fn? this)
;;TODO: this isn't kosher, it uses knowledge of internals of protocols
(-> p/StructurePath :impls (get clojure.lang.AFn))
(find-protocol-impl! p/StructurePath this)))
(-> p/Navigator :impls (get clojure.lang.AFn))
(find-protocol-impl! p/Navigator this)))
#+clj
(defn collector-impl [this]
@ -168,8 +168,8 @@
#+cljs
(defn structure-path-impl [obj]
{:select* (mk-optimized-invocation p/StructurePath obj select* 2)
:transform* (mk-optimized-invocation p/StructurePath obj transform* 2)
{:select* (mk-optimized-invocation p/Navigator obj select* 2)
:transform* (mk-optimized-invocation p/Navigator obj transform* 2)
})
#+cljs
@ -196,7 +196,7 @@
transformer (:transform* pimpl)]
(no-params-compiled-path
(->TransformFunctions
StructurePathExecutor
LeanPathExecutor
(fn [structure next-fn]
(selector this structure next-fn))
(fn [structure next-fn]
@ -217,7 +217,7 @@
)))
(defn structure-path? [obj]
(or (fn? obj) (satisfies? p/StructurePath obj)))
(or (fn? obj) (satisfies? p/Navigator obj)))
(defprotocol CoercePath
(coerce-path [this]))
@ -528,10 +528,10 @@
(into empty-structure (map #(next-fn %)) structure)
)))
(deftype AllStructurePath [])
(deftype AllNavigator [])
(extend-protocol p/StructurePath
AllStructurePath
(extend-protocol p/Navigator
AllNavigator
(select* [this structure next-fn]
(all-select structure next-fn))
(transform* [this structure next-fn]
@ -544,10 +544,10 @@
(collect-val [this structure]
structure))
(deftype PosStructurePath [getter setter])
(deftype PosNavigator [getter setter])
(extend-protocol p/StructurePath
PosStructurePath
(extend-protocol p/Navigator
PosNavigator
(select* [this structure next-fn]
(if-not (empty? structure)
(next-fn ((.-getter this) structure))))
@ -570,7 +570,7 @@
res
)))
(extend-protocol p/StructurePath
(extend-protocol p/Navigator
nil
(select* [this structure next-fn]
(next-fn structure))
@ -724,8 +724,7 @@
(instance? VarUse p)
(let [v (:var p)
vv (var-get v)]
(cond (-> v meta :dynamic)
(magic-fail! "Var " (:sym p) " is dynamic")
(cond (-> v meta :dynamic) (magic-fail! "Var " (:sym p) " is dynamic")
(valid-navigator? vv) vv
:else (magic-fail! "Var " (:sym p) " is not a navigator")
))

View file

@ -19,14 +19,14 @@
(def PARAMS-SYM (vary-meta (gensym "params") assoc :tag 'objects))
(def PARAMS-IDX-SYM (gensym "params-idx"))
(defn paramspath* [bindings num-params [impl1 impl2]]
(defn paramsnav* [bindings num-params [impl1 impl2]]
(let [[[[_ s-structure-sym s-next-fn-sym] & select-body]
[[_ t-structure-sym t-next-fn-sym] & transform-body]]
(determine-params-impls impl1 impl2)]
(if (= 0 num-params)
`(i/no-params-compiled-path
(i/->TransformFunctions
i/StructurePathExecutor
i/LeanPathExecutor
(fn [~s-structure-sym ~s-next-fn-sym]
~@select-body)
(fn [~t-structure-sym ~t-next-fn-sym]
@ -76,7 +76,7 @@
~num-params
)))
(defn pathed-path* [builder paths-seq latefns-sym pre-bindings post-bindings impls]
(defn pathed-nav* [builder paths-seq latefns-sym pre-bindings post-bindings impls]
(let [num-params-sym (gensym "num-params")]
`(let [paths# (map i/comp-paths* ~paths-seq)
needed-params# (map i/num-needed-params paths#)
@ -114,19 +114,19 @@
(apply concat)))
(defmacro path
"Defines a StructurePath with late bound parameters. This path can be precompiled
with other selectors without knowing the parameters. When precompiled with other
selectors, the resulting selector takes in parameters for all selectors in the path
(defmacro nav
"Defines a navigator with late bound parameters. This navigator can be precompiled
with other navigators without knowing the parameters. When precompiled with other
navigators, the resulting path takes in parameters for all navigators in the path
that needed parameters (in the order in which they were declared)."
[params impl1 impl2]
(let [num-params (count params)
retrieve-params (make-param-retrievers params)]
(paramspath* retrieve-params num-params [impl1 impl2])
(paramsnav* retrieve-params num-params [impl1 impl2])
))
(defmacro paramsfn [params [structure-sym] & impl]
`(path ~params
`(nav ~params
(~'select* [this# structure# next-fn#]
(let [afn# (fn [~structure-sym] ~@impl)]
(i/filter-select afn# structure# next-fn#)
@ -148,16 +148,16 @@
(paramscollector* retrieve-params num-params impl)
))
(defmacro defpath [name & body]
`(def ~name (path ~@body)))
(defmacro defnav [name & body]
`(def ~name (nav ~@body)))
(defmacro defcollector [name & body]
`(def ~name (paramscollector ~@body)))
(defmacro fixed-pathed-path
"This helper is used to define selectors that take in a fixed number of other selector
paths as input. Those selector paths may require late-bound params, so this helper
will create a parameterized selector if that is the case. If no late-bound params
(defmacro fixed-pathed-nav
"This helper is used to define navigators that take in a fixed number of other
paths as input. Those paths may require late-bound params, so this helper
will create a parameterized navigator if that is the case. If no late-bound params
are required, then the result is executable."
[bindings impl1 impl2]
(let [bindings (partition 2 bindings)
@ -165,23 +165,23 @@
names (mapv first bindings)
latefns-sym (gensym "latefns")
latefn-syms (vec (gensyms (count paths)))]
(pathed-path*
paramspath*
(pathed-nav*
paramsnav*
paths
latefns-sym
[latefn-syms latefns-sym]
(mapcat (fn [n l] [n `(~l ~PARAMS-SYM ~PARAMS-IDX-SYM)]) names latefn-syms)
[impl1 impl2])))
(defmacro variable-pathed-path
"This helper is used to define selectors that take in a variable number of other selector
paths as input. Those selector paths may require late-bound params, so this helper
will create a parameterized selector if that is the case. If no late-bound params
(defmacro variable-pathed-nav
"This helper is used to define navigators that take in a variable number of other
paths as input. Those paths may require late-bound params, so this helper
will create a parameterized navigator if that is the case. If no late-bound params
are required, then the result is executable."
[[latepaths-seq-sym paths-seq] impl1 impl2]
(let [latefns-sym (gensym "latefns")]
(pathed-path*
paramspath*
(pathed-nav*
paramsnav*
paths-seq
latefns-sym
[]
@ -198,7 +198,7 @@
[[name path] impl]
(let [latefns-sym (gensym "latefns")
latefn (gensym "latefn")]
(pathed-path*
(pathed-nav*
paramscollector*
[path]
latefns-sym

View file

@ -1,6 +1,6 @@
(ns com.rpl.specter.protocols)
(defprotocol StructurePath
(defprotocol Navigator
(select* [this structure next-fn])
(transform* [this structure next-fn]))

View file

@ -1,14 +1,14 @@
(ns com.rpl.specter.zipper
#+cljs (:require-macros
[com.rpl.specter.macros
:refer [defpath path declarepath providepath]])
:refer [defnav nav declarepath providepath]])
#+clj
(:use
[com.rpl.specter.macros :only [defpath path declarepath providepath]])
[com.rpl.specter.macros :only [defnav nav declarepath providepath]])
(:require [com.rpl.specter :as s]
[clojure.zip :as zip]))
(defpath zipper [constructor]
(defnav zipper [constructor]
(select* [this structure next-fn]
(next-fn (constructor structure)))
(transform* [this structure next-fn]
@ -30,14 +30,14 @@
s/STAY)))
(defn- mk-zip-nav [nav]
(path []
(defn- mk-zip-nav [znav]
(nav []
(select* [this structure next-fn]
(let [ret (nav structure)]
(let [ret (znav structure)]
(if ret (next-fn ret))
))
(transform* [this structure next-fn]
(let [ret (nav structure)]
(let [ret (znav structure)]
(if ret (next-fn ret) structure)
))))
@ -76,7 +76,7 @@
inserts)
))
(defpath ^{:doc "Navigate to the empty subsequence directly to the
(defnav ^{:doc "Navigate to the empty subsequence directly to the
right of this element."}
INNER-RIGHT []
(select* [this structure next-fn]
@ -85,7 +85,7 @@
(inner-insert structure next-fn zip/insert-right zip/right zip/left)
))
(defpath ^{:doc "Navigate to the empty subsequence directly to the
(defnav ^{:doc "Navigate to the empty subsequence directly to the
left of this element."}
INNER-LEFT []
(select* [this structure next-fn]
@ -94,7 +94,7 @@
(inner-insert structure next-fn zip/insert-left identity nil)
))
(defpath NODE []
(defnav NODE []
(select* [this structure next-fn]
(next-fn (zip/node structure))
)
@ -102,7 +102,7 @@
(zip/edit structure next-fn)
))
(defpath ^{:doc "Navigate to the subsequence containing only
(defnav ^{:doc "Navigate to the subsequence containing only
the node currently pointed to. This works just
like srange and can be used to remove elements
from the structure"}

View file

@ -4,15 +4,15 @@
[cljs.test.check.cljs-test :refer [defspec]]
[com.rpl.specter.cljs-test-helpers :refer [for-all+]]
[com.rpl.specter.macros
:refer [paramsfn defprotocolpath defpath extend-protocolpath
declarepath providepath]])
:refer [paramsfn defprotocolpath defnav extend-protocolpath
nav declarepath providepath]])
(:use
#+clj [clojure.test :only [deftest is]]
#+clj [clojure.test.check.clojure-test :only [defspec]]
#+clj [com.rpl.specter.test-helpers :only [for-all+]]
#+clj [com.rpl.specter.macros
:only [paramsfn defprotocolpath defpath extend-protocolpath
declarepath providepath]]
:only [paramsfn defprotocolpath defnav extend-protocolpath
nav declarepath providepath]]
)
@ -603,8 +603,8 @@
val (gen/elements (range 10))
op (gen/elements [inc dec])
comparator (gen/elements [= > <])]
(let [path (s/comp-paths s/ALL (paramsfn [p] [v] (comparator v p)))]
(= (s/transform (path val) op v)
(let [cpath (s/comp-paths s/ALL (paramsfn [p] [v] (comparator v p)))]
(= (s/transform (cpath val) op v)
(s/transform [s/ALL #(comparator % val)] op v)))
))