While adding the live reload feature to Clay, I encountered a problem of applying anonymous functions to thread macros. For example, below is a simple snippet trying to wrap the input directory as a vector with the help of thread macro, but surprisingly, it errors out. After some searching, I figured out that I need to put the anonymous function into another pair of parentheses:
(-> "/tmp/"
#(if (vector? %) % [%]))
;; => Syntax error (ClassCastException) compiling fn* at (simple4all.clj:19:1).
;; class java.lang.String cannot be cast to class clojure.lang.ISeq (java.lang.String is in module java.base of loader 'bootstrap'; clojure.lang.ISeq is in unnamed module of loader 'app')
(-> "/tmp/"
(#(if (vector? %) % [%])))
;; => ["/tmp/"]
Paul has a nice explanation on Stack Overflow, thread macros need the function forms to be lists, but anonymous functions are already lists, so the first expression, "/tmp/"
in this example, will just be inserted into that list, just as illustrated below:
(macroexpand '#(if (vector? %) % [%]))
;; => (fn* [p1__11055#] (if (vector? p1__11055#) p1__11055# [p1__11055#]))
(macroexpand '(-> "/tmp/"
#(if (vector? %) % [%])))
;; => (fn*
;; "/tmp/"
;; [p1__11079#]
;; (if (vector? p1__11079#) p1__11079# [p1__11079#]))