Compare commits
2 commits
master
...
lean-execu
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bde18388d7 | ||
|
|
3f26eb1826 |
3 changed files with 103 additions and 33 deletions
|
|
@ -15,11 +15,7 @@
|
||||||
"Navigates to and returns a sequence of all the elements specified by the selector."
|
"Navigates to and returns a sequence of all the elements specified by the selector."
|
||||||
[selector structure]
|
[selector structure]
|
||||||
(let [sp (comp-paths* selector)]
|
(let [sp (comp-paths* selector)]
|
||||||
(select-full* sp
|
(exec-select selector structure)
|
||||||
[]
|
|
||||||
structure
|
|
||||||
(fn [vals structure]
|
|
||||||
(if-not (empty? vals) [(conj vals structure)] [structure])))
|
|
||||||
))
|
))
|
||||||
|
|
||||||
(defn select-one
|
(defn select-one
|
||||||
|
|
@ -51,14 +47,8 @@
|
||||||
the update-fn on it"
|
the update-fn on it"
|
||||||
[selector update-fn structure]
|
[selector update-fn structure]
|
||||||
(let [selector (comp-paths* selector)]
|
(let [selector (comp-paths* selector)]
|
||||||
(update-full* selector
|
(exec-update selector update-fn structure)
|
||||||
[]
|
))
|
||||||
structure
|
|
||||||
(fn [vals structure]
|
|
||||||
(if (empty? vals)
|
|
||||||
(update-fn structure)
|
|
||||||
(apply update-fn (conj vals structure)))
|
|
||||||
))))
|
|
||||||
|
|
||||||
(defn setval
|
(defn setval
|
||||||
"Navigates to each value specified by the selector and replaces it by val"
|
"Navigates to each value specified by the selector and replaces it by val"
|
||||||
|
|
|
||||||
|
|
@ -9,14 +9,10 @@
|
||||||
(dotimes [_ iters]
|
(dotimes [_ iters]
|
||||||
(afn))))
|
(afn))))
|
||||||
|
|
||||||
(defprotocol CoerceStructureValsPath
|
(defprotocol CoercePath
|
||||||
(coerce-path [this]))
|
(coerce-path [this]))
|
||||||
|
|
||||||
(extend-protocol CoerceStructureValsPath
|
(extend-protocol CoercePath
|
||||||
|
|
||||||
com.rpl.specter.protocols.StructureValsPath
|
|
||||||
(coerce-path [this] this)
|
|
||||||
|
|
||||||
com.rpl.specter.protocols.Collector
|
com.rpl.specter.protocols.Collector
|
||||||
(coerce-path [collector]
|
(coerce-path [collector]
|
||||||
(reify StructureValsPath
|
(reify StructureValsPath
|
||||||
|
|
@ -28,22 +24,74 @@
|
||||||
;; need to say Object instead of StructurePath so that things like Keyword are properly coerced
|
;; need to say Object instead of StructurePath so that things like Keyword are properly coerced
|
||||||
Object
|
Object
|
||||||
(coerce-path [spath]
|
(coerce-path [spath]
|
||||||
|
spath))
|
||||||
|
|
||||||
|
(defprotocol CoerceStructureValsPath
|
||||||
|
(coerce-structure-vals-path [this]))
|
||||||
|
|
||||||
|
(extend-protocol CoerceStructureValsPath
|
||||||
|
com.rpl.specter.protocols.StructureValsPath
|
||||||
|
(coerce-structure-vals-path [this] this)
|
||||||
|
|
||||||
|
com.rpl.specter.protocols.Collector
|
||||||
|
(coerce-structure-vals-path [this] (coerce-path this))
|
||||||
|
|
||||||
|
|
||||||
|
;; need to say Object instead of StructurePath so that things like Keyword are properly coerced
|
||||||
|
Object
|
||||||
|
(coerce-structure-vals-path [spath]
|
||||||
(reify StructureValsPath
|
(reify StructureValsPath
|
||||||
(select-full* [this vals structure next-fn]
|
(select-full* [this vals structure next-fn]
|
||||||
(select* spath structure (fn [structure] (next-fn vals structure))))
|
(select* spath structure (fn [structure] (next-fn vals structure))))
|
||||||
(update-full* [this vals structure next-fn]
|
(update-full* [this vals structure next-fn]
|
||||||
(update* spath structure (fn [structure] (next-fn vals structure)))
|
(update* spath structure (fn [structure] (next-fn vals structure)))
|
||||||
)))
|
))))
|
||||||
)
|
|
||||||
|
|
||||||
|
(defn- combine-same-types [[f & _ :as all]]
|
||||||
|
(cond (extends? StructureValsPath (class f))
|
||||||
|
all
|
||||||
|
|
||||||
(extend-protocol StructureValsPathComposer
|
(extends? Collector (class f))
|
||||||
|
[(reify StructureValsPath
|
||||||
|
(select-full* [this vals structure next-fn]
|
||||||
|
(next-fn (reduce conj vals (for [c all] (collect-val c structure))) structure))
|
||||||
|
(update-full* [this vals structure next-fn]
|
||||||
|
(next-fn (reduce conj vals (for [c all] (collect-val c structure))) structure))
|
||||||
|
)]
|
||||||
|
|
||||||
|
:else
|
||||||
|
[(reduce (fn [curr sp]
|
||||||
|
(reify StructurePath
|
||||||
|
(select* [this structure next-fn]
|
||||||
|
(select* sp structure
|
||||||
|
(fn [structure-next]
|
||||||
|
(select* curr structure-next next-fn))))
|
||||||
|
(update* [this structure next-fn]
|
||||||
|
(update* sp structure
|
||||||
|
(fn [structure-next]
|
||||||
|
(update* curr structure-next next-fn))))
|
||||||
|
))
|
||||||
|
(reverse all))]))
|
||||||
|
|
||||||
|
(defprotocol PathComposer
|
||||||
|
(comp-paths* [paths]))
|
||||||
|
|
||||||
|
(extend-protocol PathComposer
|
||||||
Object
|
Object
|
||||||
(comp-paths* [sp]
|
(comp-paths* [sp]
|
||||||
(coerce-path sp))
|
(coerce-path sp))
|
||||||
java.util.List
|
java.util.List
|
||||||
(comp-paths* [structure-paths]
|
(comp-paths* [structure-paths]
|
||||||
(reduce (fn [sp-curr sp]
|
(let [combined (->> structure-paths
|
||||||
|
flatten
|
||||||
|
(partition-by (fn [e]
|
||||||
|
(cond (extends? StructureValsPath (class e)) :svalspath
|
||||||
|
(extends? Collector (class e)) :collector
|
||||||
|
:else :spath)))
|
||||||
|
(mapcat combine-same-types))]
|
||||||
|
(if (= 1 (count combined))
|
||||||
|
(first combined)
|
||||||
|
(reduce (fn [sp-curr sp]
|
||||||
(reify StructureValsPath
|
(reify StructureValsPath
|
||||||
(select-full* [this vals structure next-fn]
|
(select-full* [this vals structure next-fn]
|
||||||
(select-full* sp vals structure
|
(select-full* sp vals structure
|
||||||
|
|
@ -55,7 +103,35 @@
|
||||||
(fn [vals-next structure-next]
|
(fn [vals-next structure-next]
|
||||||
(update-full* sp-curr vals-next structure-next next-fn))))
|
(update-full* sp-curr vals-next structure-next next-fn))))
|
||||||
))
|
))
|
||||||
(->> structure-paths flatten (map coerce-path) reverse))
|
(->> structure-paths (map coerce-structure-vals-path) reverse))
|
||||||
|
))))
|
||||||
|
|
||||||
|
(defprotocol Executor
|
||||||
|
(exec-select [selector structure])
|
||||||
|
(exec-update [selector update-fn structure]))
|
||||||
|
|
||||||
|
(extend-protocol Executor
|
||||||
|
com.rpl.specter.protocols.StructureValsPath
|
||||||
|
(exec-select [selector structure]
|
||||||
|
(select-full* selector
|
||||||
|
[]
|
||||||
|
structure
|
||||||
|
(fn [vals structure]
|
||||||
|
(if-not (empty? vals) [(conj vals structure)] [structure]))))
|
||||||
|
(exec-update [selector update-fn structure]
|
||||||
|
(update-full* selector
|
||||||
|
[]
|
||||||
|
structure
|
||||||
|
(fn [vals structure]
|
||||||
|
(if (empty? vals)
|
||||||
|
(update-fn structure)
|
||||||
|
(apply update-fn (conj vals structure))))))
|
||||||
|
|
||||||
|
Object
|
||||||
|
(exec-select [selector structure]
|
||||||
|
(select* selector structure (fn [e] [e])))
|
||||||
|
(exec-update [selector update-fn structure]
|
||||||
|
(update* selector structure update-fn)
|
||||||
))
|
))
|
||||||
|
|
||||||
;; cell implementation idea taken from prismatic schema library
|
;; cell implementation idea taken from prismatic schema library
|
||||||
|
|
@ -117,8 +193,8 @@
|
||||||
|
|
||||||
(defn- walk-until [pred on-match-fn structure]
|
(defn- walk-until [pred on-match-fn structure]
|
||||||
(if (pred structure)
|
(if (pred structure)
|
||||||
(on-match-fn structure)
|
(on-match-fn structure)
|
||||||
(walk/walk (partial walk-until pred on-match-fn) identity structure)
|
(walk/walk (partial walk-until pred on-match-fn) identity structure)
|
||||||
))
|
))
|
||||||
|
|
||||||
(defn- fn-invocation? [f]
|
(defn- fn-invocation? [f]
|
||||||
|
|
@ -130,7 +206,7 @@
|
||||||
(if (pred structure)
|
(if (pred structure)
|
||||||
(on-match-fn structure)
|
(on-match-fn structure)
|
||||||
(let [ret (walk/walk (partial codewalk-until pred on-match-fn) identity structure)]
|
(let [ret (walk/walk (partial codewalk-until pred on-match-fn) identity structure)]
|
||||||
(if (and (fn-invocation? structure) (fn-invocation? ret))
|
(if (and (fn-invocation? structure) (fn-invocation? ret))
|
||||||
(with-meta ret (meta structure))
|
(with-meta ret (meta structure))
|
||||||
ret
|
ret
|
||||||
))))
|
))))
|
||||||
|
|
@ -159,7 +235,7 @@
|
||||||
[(conj s e) (assoc m pos i)]
|
[(conj s e) (assoc m pos i)]
|
||||||
orig
|
orig
|
||||||
)))
|
)))
|
||||||
[[] {}]
|
[[] {}]
|
||||||
(range (count aseq))
|
(range (count aseq))
|
||||||
)))
|
)))
|
||||||
|
|
||||||
|
|
@ -269,6 +345,3 @@
|
||||||
(update* [this structure next-fn]
|
(update* [this structure next-fn]
|
||||||
(-> structure view-fn next-fn)
|
(-> structure view-fn next-fn)
|
||||||
))
|
))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,10 @@
|
||||||
(ns com.rpl.specter.protocols)
|
(ns com.rpl.specter.protocols)
|
||||||
|
|
||||||
|
|
||||||
|
;;TODO: might be able to speed it up more by having these return a function rather than
|
||||||
|
;;rely on protocol methods (can then compose functions together directly)
|
||||||
|
;;so protocol would just be used during composition - what about execution?
|
||||||
|
;;could have a select-fast function that takes in a selector FUNCTION explicitly
|
||||||
(defprotocol StructureValsPath
|
(defprotocol StructureValsPath
|
||||||
(select-full* [this vals structure next-fn])
|
(select-full* [this vals structure next-fn])
|
||||||
(update-full* [this vals structure next-fn]))
|
(update-full* [this vals structure next-fn]))
|
||||||
|
|
@ -12,5 +16,8 @@
|
||||||
(defprotocol Collector
|
(defprotocol Collector
|
||||||
(collect-val [this structure]))
|
(collect-val [this structure]))
|
||||||
|
|
||||||
(defprotocol StructureValsPathComposer
|
;;TODO: Collectors in sequence become a StructureValsPath that does all collection at once
|
||||||
(comp-paths* [paths]))
|
;;StructurePath in sequence become a single StructurePath
|
||||||
|
;;any StructureValsPath composed with anything becomes a StructureValsPath
|
||||||
|
;;TODO: update update/select to be able to execute a StructurePath directly without coercing it
|
||||||
|
;; - this will avoid MANY layers of indirection and overhead
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue