diff --git a/src/clj/com/rpl/specter/impl.cljx b/src/clj/com/rpl/specter/impl.cljx index 419ea83..55ee39b 100644 --- a/src/clj/com/rpl/specter/impl.cljx +++ b/src/clj/com/rpl/specter/impl.cljx @@ -123,6 +123,8 @@ (com.rpl.specter.impl/bind-params* this a 0)) )) +(defn params-needed-path? [o] + (instance? ParamsNeededPath o)) (defn bind-params* [^ParamsNeededPath params-needed-path params idx] (->CompiledPath diff --git a/src/clj/com/rpl/specter/macros.clj b/src/clj/com/rpl/specter/macros.clj index 2763dc7..09d66f0 100644 --- a/src/clj/com/rpl/specter/macros.clj +++ b/src/clj/com/rpl/specter/macros.clj @@ -79,6 +79,10 @@ `(let [paths# (map comp-paths* ~paths-seq) needed-params# (map num-needed-params paths#) offsets# (cons 0 (reductions + needed-params#)) + any-params-needed?# (->> paths# + (filter params-needed-path?) + empty? + not) ~num-params-sym (last offsets#) ~latefns-sym (map (fn [o# p#] @@ -93,7 +97,7 @@ ~@pre-bindings ret# ~(builder post-bindings num-params-sym impls) ] - (if (= 0 ~num-params-sym) + (if (not any-params-needed?#) (bind-params* ret# nil 0) ret# )))) diff --git a/test/com/rpl/specter/core_test.cljx b/test/com/rpl/specter/core_test.cljx index 2442ab2..596bc93 100644 --- a/test/com/rpl/specter/core_test.cljx +++ b/test/com/rpl/specter/core_test.cljx @@ -642,6 +642,22 @@ (is (= {3 21 4 31} (s/transform [s/ALL s/ALL] inc {2 20 3 30}))) ) +(declarepath NestedHigherOrderWalker [k]) + +(providepath NestedHigherOrderWalker + (s/if-path vector? + (s/if-path [s/FIRST (paramsfn [k] [e] (= k e))] + (s/continue-then-stay s/ALL (s/params-reset NestedHigherOrderWalker)) + [s/ALL (s/params-reset NestedHigherOrderWalker)] + ))) + +(deftest nested-higher-order-walker-test + (is (= [:q [:abc :I 3] [:ccc [:abc :I] [:abc :I "a" [:abc :I [:abc :I [:d]]]]]] + (s/setval [(NestedHigherOrderWalker :abc) (s/srange 1 1)] + [:I] + [:q [:abc 3] [:ccc [:abc] [:abc "a" [:abc [:abc [:d]]]]]] + )))) + #+clj (deftest large-params-test (let [path (apply s/comp-paths (repeat 25 s/keypath))