broken implementation of skipping protocols

This commit is contained in:
Nathan Marz 2015-05-10 02:12:06 -04:00
parent 277735dd9b
commit 47aee4d000
4 changed files with 69 additions and 28 deletions

View file

@ -4,6 +4,7 @@
:jvm-opts ["-XX:-OmitStackTraceInFastThrow"] ; this prevents JVM from doing optimizations which can remove stack traces from NPE and other exceptions :jvm-opts ["-XX:-OmitStackTraceInFastThrow"] ; this prevents JVM from doing optimizations which can remove stack traces from NPE and other exceptions
:source-paths ["src/clj"] :source-paths ["src/clj"]
:test-paths ["test/clj"] :test-paths ["test/clj"]
:plugins [[lein-nodisassemble "0.1.3"]]
:profiles {:dev {:dependencies :profiles {:dev {:dependencies
[[org.clojure/test.check "0.5.9"]]} [[org.clojure/test.check "0.5.9"]]}
}) })

View file

@ -22,6 +22,13 @@
(if-not (empty? vals) [(conj vals structure)] [structure]))) (if-not (empty? vals) [(conj vals structure)] [structure])))
)) ))
(defn select-fast
[^com.rpl.specter.impl.StructureValsPathFunctions selfns structure]
((.selector selfns) [] structure
(fn [vals structure]
(if-not (empty? vals) [(conj vals structure)] [structure])))
)
(defn select-one (defn select-one
"Like select, but returns either one element or nil. Throws exception if multiple elements found" "Like select, but returns either one element or nil. Throws exception if multiple elements found"
[selector structure] [selector structure]

View file

@ -9,31 +9,55 @@
(dotimes [_ iters] (dotimes [_ iters]
(afn)))) (afn))))
(defprotocol CoerceStructureValsPath (deftype StructureValsPathFunctions [selector updater]
StructureValsPath
(select-full* [this vals structure next-fn]
(selector vals structure next-fn))
(update-full* [this vals structure next-fn]
(updater vals structure next-fn)))
(defprotocol CoerceStructureValsPathFunctions
(coerce-path [this])) (coerce-path [this]))
(extend-protocol CoerceStructureValsPath (extend-protocol CoerceStructureValsPathFunctions
com.rpl.specter.protocols.StructureValsPath com.rpl.specter.protocols.StructureValsPath
(coerce-path [this] this) (coerce-path [this]
(let [pimpl (->> this
(find-protocol-impl StructureValsPath))
selector (:select-full* pimpl)
updater (:update-full* pimpl)]
(->StructureValsPathFunctions
(fn [vals structure next-fn]
(selector this vals structure next-fn))
(fn [vals structure next-fn]
(updater this vals structure next-fn)))
))
com.rpl.specter.protocols.Collector com.rpl.specter.protocols.Collector
(coerce-path [collector] (coerce-path [collector]
(reify StructureValsPath (let [pimpl (->> collector
(select-full* [this vals structure next-fn] (find-protocol-impl Collector)
(next-fn (conj vals (collect-val collector structure)) structure)) :collect-val
(update-full* [this vals structure next-fn] )
(next-fn (conj vals (collect-val collector structure)) structure)))) afn (fn [vals structure next-fn]
(next-fn (conj vals (pimpl collector structure)) structure)
)]
(->StructureValsPathFunctions afn afn)))
;; 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 [this]
(reify StructureValsPath (let [pimpl (->> this
(select-full* [this vals structure next-fn] (find-protocol-impl StructurePath))
(select* spath structure (fn [structure] (next-fn vals structure)))) selector (:select* pimpl)
(update-full* [this vals structure next-fn] updater (:update* pimpl)]
(update* spath structure (fn [structure] (next-fn vals structure))) (->StructureValsPathFunctions
))) (fn [vals structure next-fn]
(selector this structure (fn [structure] (next-fn vals structure))))
(fn [vals structure next-fn]
(updater this structure (fn [structure] (next-fn vals structure))))
)))
) )
@ -43,18 +67,26 @@
(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] ;;TODO: don't reify any protocols... instead coerce to a "StructureValsPathFunctions" record
(reify StructureValsPath ;; and compose functions directly
(select-full* [this vals structure next-fn]
(select-full* sp vals structure (reduce (fn [^StructureValsPathFunctions sp-curr ^StructureValsPathFunctions sp]
(fn [vals-next structure-next] (let [curr-selector (.selector sp-curr)
(select-full* sp-curr vals-next structure-next next-fn))) selector (.selector sp)
) curr-updater (.updater sp-curr)
(update-full* [this vals structure next-fn] updater (.updater sp)]
(update-full* sp vals structure (->StructureValsPathFunctions
(fn [vals-next structure-next] (fn [vals structure next-fn]
(update-full* sp-curr vals-next structure-next next-fn)))) (selector vals structure
)) (fn [vals-next structure-next]
(curr-selector vals-next structure-next next-fn)
)))
(fn [vals structure next-fn]
(updater vals structure
(fn [vals-next structure-next]
(curr-updater vals-next structure-next next-fn)
)))
)))
(->> structure-paths flatten (map coerce-path) reverse)) (->> structure-paths flatten (map coerce-path) reverse))
)) ))

View file

@ -1,6 +1,7 @@
(ns com.rpl.specter.protocols) (ns com.rpl.specter.protocols)
;;TODO: can use find-protocol-impl function to avoid all the protocol calls
(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]))