From df4c3bf9740cab164640e6e728adb925e850a8df Mon Sep 17 00:00:00 2001 From: Nathan Marz Date: Sun, 20 Sep 2015 22:24:11 -0400 Subject: [PATCH] added paramsfn helper macro for defining filter functions with later bound parameters --- CHANGES.md | 1 + src/com/rpl/specter/macros.clj | 11 +++++++++++ test/com/rpl/specter/core_test.cljc | 12 ++++++++++++ 3 files changed, 24 insertions(+) diff --git a/CHANGES.md b/CHANGES.md index d615f9d..149daa5 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,6 +1,7 @@ ## 0.7.1 (unreleased) * view can now be late-bound parameterized * Added a late-bound parameterized version of using a function as a selector called "pred" +* Added paramsfn helper macro for defining filter functions that take late-bound parameters ## 0.7.0 * Added late-bound parameterization feauture: allows selectors that require params to be precompiled without the parameters, and the parameters are supplied later in bulk. This effectively enables Specter to be used in any situation with very high performance. diff --git a/src/com/rpl/specter/macros.clj b/src/com/rpl/specter/macros.clj index 32f8da9..6ee6757 100644 --- a/src/com/rpl/specter/macros.clj +++ b/src/com/rpl/specter/macros.clj @@ -107,6 +107,17 @@ (paramspath* retrieve-params num-params impls) )) +(defmacro paramsfn [params [structure-sym] & impl] + `(paramspath ~params + (~'select* [this# structure# next-fn#] + (let [afn# (fn [~structure-sym] ~@impl)] + (filter-select afn# structure# next-fn#) + )) + (~'transform* [this# structure# next-fn#] + (let [afn# (fn [~structure-sym] ~@impl)] + (filter-transform afn# structure# next-fn#) + )))) + (defmacro paramscollector "Defines a Collector with late bound parameters. This collector can be precompiled with other selectors without knowing the parameters. When precompiled with other diff --git a/test/com/rpl/specter/core_test.cljc b/test/com/rpl/specter/core_test.cljc index 28d7965..f3786d5 100644 --- a/test/com/rpl/specter/core_test.cljc +++ b/test/com/rpl/specter/core_test.cljc @@ -13,6 +13,7 @@ [cljs.test.check.generators :as gen] [cljs.test.check.properties :as prop :include-macros true]] ) + [com.rpl.specter.macros :as m] [com.rpl.specter :as s])) ;;TODO: @@ -523,6 +524,17 @@ )) )))) +(defspec paramsfn-test + (for-all+ + [v (gen/vector (gen/elements (range 10))) + val (gen/elements (range 10)) + op (gen/elements [inc dec]) + comparator (gen/elements [= > <])] + (let [path (s/comp-paths s/ALL (m/paramsfn [p] [v] (comparator v p)))] + (= (s/transform (path val) op v) + (s/transform [s/ALL #(comparator % val)] op v))) + )) + #?(:clj (deftest large-params-test (let [path (apply s/comp-paths (repeat 25 s/keypath))