Hello! Thank you for the library! It is great 🙂
Recently I upgraded Clojure on one of our projects that uses Specter and noticed that one test case failed with a compilation error when it tried to build a path containing nil?
Unable to resolve var: clojure.lang.Util/identical in this context
It might be related to https://insideclojure.org/2024/02/12/method-values/
(riddley/macroexpand-all '(nil? nil)) ;; => (clojure.lang.Util/identical nil nil)
before 1.12.0-alpha6 nil? expanded to (. clojure.lang.Util identical nil nil)
I don’t fully understand how magic-precompilation works and what is expected there.
This little patch where I try to resolve on symbol’s namespace fixes the compilation issue but I’m not confident it is the right solution:
diff --git a/src/clj/com/rpl/specter.cljc b/src/clj/com/rpl/specter.cljc
index e83bf43..5f2aed2 100644
--- a/src/clj/com/rpl/specter.cljc
+++ b/src/clj/com/rpl/specter.cljc
@@ -199,17 +199,19 @@
(symbol? path)
(if (contains? locals-set path)
(let [s (get locals-set path)
embed (i/maybe-direct-nav path (-> s meta :direct-nav))]
`(com.rpl.specter.impl/->LocalSym ~path (quote ~embed)))
;; var-get doesn't work in cljs, so capture the val in the macro instead
`(com.rpl.specter.impl/->VarUse
~path
- ~(if-not (instance? Class (resolve path)) `(var ~path))
+ ~(if-not (instance? Class (or (resolve path)
+ (some-> path namespace symbol resolve)))
+ `(var ~path))
(quote ~path)))
(i/fn-invocation? path)
(let [[op & params] path]
;; need special case for 'fn since macroexpand does NOT
;; expand fn when run on cljs code, but it's also not considered a special symbol
(if (or (= 'fn op) (special-symbol? op))
--can you provide code that reproduces the issue?
I haven't seen this using it with 1.12.4, and using nil? in a path is very common
Hello! This is the exact function which failed to compile on with Clojure newer than 1.12.0-alpha5:
(defn convert-ignore-case-flag
[ignore-case? new-operator condition]
(transform
(constantly (not (nil? ignore-case?)))
(fn [condition]
(if (= new-operator :matches-regex)
(transform [:params (must 1) (must :values) ALL]
make-regex-case-insensitive
condition)
(setval [:ignore-case?] ignore-case? condition)))
condition))ah I see, it's a bad interaction between Clojure inlining nil? and the inline compiler for Specter
you can work around it with something like (let [f (constantly (not (nil? ignore-case?)))] (transform (pred f) ...
Awesome, it will do! Thanks for putting your work into the library :)