<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0">
<channel>
<title>Clojure Q&amp;A - Recent activity in Macros</title>
<link>https://ask.clojure.org/index.php/activity/clojure/macros</link>
<description></description>
<item>
<title>Commented: Adding condp-&gt; and condp-&gt;&gt; macros to core library</title>
<link>https://ask.clojure.org/index.php/2365/adding-condp-and-condp-macros-to-core-library?show=15091#c15091</link>
<description>This invokes the predicates on the expression. We have a version that _threads_ the expression through the predicate: &lt;a href=&quot;https://github.com/worldsingles/commons/blob/master/src/ws/clojure/extensions.clj#L24&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;https://github.com/worldsingles/commons/blob/master/src/ws/clojure/extensions.clj#L24&lt;/a&gt;</description>
<category>Macros</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/2365/adding-condp-and-condp-macros-to-core-library?show=15091#c15091</guid>
<pubDate>Wed, 20 May 2026 14:17:09 +0000</pubDate>
</item>
<item>
<title>Closed: Why doesn't defn also implicitly name the anonymous function it defines for recursion?</title>
<link>https://ask.clojure.org/index.php/15000/doesnt-defn-implicitly-anonymous-function-defines-recursion?show=15000#q15000</link>
<description>&lt;p&gt;Why doesn't &lt;code&gt;defn&lt;/code&gt; implicitly name the function to create a named recursion point?&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(clojure.walk/macroexpand-all
  '(defn foo [x]
     (foo x)))
; =&amp;gt;
(def foo
  (fn*
    ([x]
     (foo x))))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This could instead expand to&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(def foo
  (fn* foo ; note the foo here
    ([x]
     (foo x))))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;How it works right now, &lt;code&gt;foo&lt;/code&gt; resolves to a global var &lt;code&gt;#'foo&lt;/code&gt;, which is created when the &lt;code&gt;(def ...)&lt;/code&gt; form is analyzed. In the second case, it resolves directly to the function object. Thus, it should save us a var dereference at runtime in this case.&lt;/p&gt;
&lt;p&gt;EDIT: Found out, this is exactly what &lt;a rel=&quot;nofollow&quot; href=&quot;https://clojure.org/reference/compilation#directlinking&quot;&gt;direct linking&lt;/a&gt; is used for.&lt;/p&gt;
</description>
<category>Macros</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/15000/doesnt-defn-implicitly-anonymous-function-defines-recursion?show=15000#q15000</guid>
<pubDate>Thu, 26 Mar 2026 17:24:24 +0000</pubDate>
</item>
<item>
<title>Commented: specifying `:let` as the first element of `for` causes an macro expansion error</title>
<link>https://ask.clojure.org/index.php/14670/specifying-let-first-element-causes-macro-expansion-error?show=14678#c14678</link>
<description>Possibly, but the extra check on the vector would be a performance penalty that everyone would pay for every use of `for` in every program -- and Clojure rarely does that to its users.</description>
<category>Macros</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/14670/specifying-let-first-element-causes-macro-expansion-error?show=14678#c14678</guid>
<pubDate>Mon, 11 Aug 2025 19:54:20 +0000</pubDate>
</item>
<item>
<title>Comment edited: `cond-let` macro as pair for `if-let`, similar to `if`/`conf` pair</title>
<link>https://ask.clojure.org/index.php/12912/cond-let-macro-as-pair-for-if-let-similar-to-if-conf-pair?show=14540#c14540</link>
<description>I do sometimes &amp;quot;need&amp;quot; something like this. Very concrete example:&lt;br /&gt;
&lt;br /&gt;
```&lt;br /&gt;
(cond-let&lt;br /&gt;
&amp;nbsp;&amp;nbsp;[search-results1 (check1-involving-heavy-work)] {:result search-results1}&lt;br /&gt;
&amp;nbsp;&amp;nbsp;[search-results2 (check2-involving-heavy-work)] {:result search-results2}&lt;br /&gt;
&amp;nbsp;&amp;nbsp;[search-results3 (check3-involving-heavy-work)] {:result search-results3}&lt;br /&gt;
&amp;nbsp;&amp;nbsp;[search-results4 (check4-involving-heavy-work)] {:result search-results4}&lt;br /&gt;
&amp;nbsp;&amp;nbsp;:else ...)&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
I found this: &lt;a href=&quot;https://cljdoc.org/d/org.flatland/useful/0.11.6/api/flatland.useful.experimental#cond-let&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;https://cljdoc.org/d/org.flatland/useful/0.11.6/api/flatland.useful.experimental#cond-let&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
Not sure why it is &amp;quot;experimental&amp;quot;, but this seems to be, well, useful to me :)&lt;br /&gt;
&lt;br /&gt;
(* updated to make example a bit more clear; it's a hypothetical example, don't pin me down on the details and how you could do this exact example differently please :) *)</description>
<category>Macros</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/12912/cond-let-macro-as-pair-for-if-let-similar-to-if-conf-pair?show=14540#c14540</guid>
<pubDate>Thu, 08 May 2025 12:35:57 +0000</pubDate>
</item>
<item>
<title>Retagged: `doseq` and `for` expands body twice</title>
<link>https://ask.clojure.org/index.php/14433/doseq-and-for-expands-body-twice?show=14433#q14433</link>
<description>&lt;p&gt;The bodies of &lt;code&gt;doseq&lt;/code&gt; and &lt;code&gt;for&lt;/code&gt; seem to be duplicated in their expansions.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ clojure
user=&amp;gt; (defmacro a [] (prn :expand))
#'user/a
user=&amp;gt; (doseq [_ nil] (a))
:expand
:expand
nil
user=&amp;gt; (for [_ nil] (a))
:expand
:expand
()
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I found the same problem in ClojureScript. I could not find an existing discussion about this so I'm not sure if this is by design, apologies if so. I'm aware that these macros have a large code footprint and that &lt;code&gt;doseq&lt;/code&gt; cannot use closures (the usual way to prevent exponential expansion), but I missed this detail.&lt;/p&gt;
&lt;p&gt;This leads to exponential code blowup if these forms are nested. Artificial demonstration:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ clojure
Clojure 1.12.0
user=&amp;gt; (def counter (atom -1))
#'user/counter
user=&amp;gt; (defmacro a [] (prn :expand (swap! counter inc)))
#'user/a
user=&amp;gt; #(doseq [_ 1] (doseq [_ 2] (doseq [_ 3] (doseq [_ 4] (a)))))
:expand 0
:expand 1
:expand 2
:expand 3
:expand 4
:expand 5
:expand 6
:expand 7
:expand 8
:expand 9
:expand 10
:expand 11
:expand 12
:expand 13
:expand 14
:expand 15
#object[user$eval926$fn__927 0x76563d26 &quot;user$eval926$fn__927@76563d26&quot;]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This might be especially relevant to core.async, where placing &lt;code&gt;go&lt;/code&gt; under &lt;code&gt;doseq&lt;/code&gt; is idiomatic, since &lt;code&gt;go&lt;/code&gt; is expensive in both expansion time and code size.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;user=&amp;gt; (time (eval '(doseq [_ nil] (a/go (doseq [_ nil] (a/go (doseq [_ nil] (a/go))))))))
&quot;Elapsed time: 837.230917 msecs&quot;
nil
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It also leads to duplicated reflection warnings from the fully expanded forms, which is how I found this problem.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;user=&amp;gt; (doseq [_ nil] (Thread/sleep (identity 1)))
Reflection warning, NO_SOURCE_PATH:1:16 - call to static method sleep on java.lang.Thread can't be resolved (argument types: unknown).
Reflection warning, NO_SOURCE_PATH:1:16 - call to static method sleep on java.lang.Thread can't be resolved (argument types: unknown).
nil
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I believe the exponential expansion for &lt;code&gt;doseq&lt;/code&gt; was introduced in Clojure 1.1.0 with support for chunked seqs with &lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/clojure/clojure/commit/1abb7a56de1678321054af7fce183184f06974dd&quot;&gt;this commit&lt;/a&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ clojure -Sdeps '{:deps {org.clojure/clojure {:mvn/version &quot;1.0.0&quot;}}}' 
Downloading: org/clojure/clojure/1.0.0/clojure-1.0.0.pom from central
Downloading: org/clojure/clojure/1.0.0/clojure-1.0.0.jar from central
Clojure 1.0.0-
user=&amp;gt; (defmacro a [] (prn :expand))
#'user/a
user=&amp;gt; (doseq [_ nil] (a))
:expand
nil
user=&amp;gt; ^D
$ clojure -Sdeps '{:deps {org.clojure/clojure {:mvn/version &quot;1.1.0&quot;}}}'
Downloading: org/clojure/clojure/1.1.0/clojure-1.1.0.pom from central
Downloading: org/clojure/clojure/1.1.0/clojure-1.1.0.jar from central
Clojure 1.1.0
user=&amp;gt; (defmacro a [] (prn :expand))
#'user/a
user=&amp;gt; (doseq [_ nil] (a))
:expand
:expand
nil
user=&amp;gt; 
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;At first I wasn't sure if this was hopeless, but I think &lt;code&gt;doseq&lt;/code&gt; is fixable fusing the chunked and non-chunked cases like so:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(defmacro doseq
  &quot;Repeatedly executes body (presumably for side-effects) with
  bindings and filtering as provided by \&quot;for\&quot;.  Does not retain
  the head of the sequence. Returns nil.
  
  Unlike clojure.core/doseq, does not cause exponential macro expansion
  of expressions in bindings or body.&quot;
  [seq-exprs &amp;amp; body]
  (#'clojure.core/assert-args
     (vector? seq-exprs) &quot;a vector for its binding&quot;
     (even? (count seq-exprs)) &quot;an even number of forms in binding vector&quot;)
  (let [step (fn step [recform exprs]
               (if-not exprs
                 [true `(do ~@body)]
                 (let [k (first exprs)
                       v (second exprs)]
                   (if (keyword? k)
                     (let [steppair (step recform (nnext exprs))
                           needrec (steppair 0)
                           subform (steppair 1)]
                       (cond
                         (= k :let) [needrec `(let ~v ~subform)]
                         (= k :while) [false `(when ~v
                                                ~subform
                                                ~@(when needrec [recform]))]
                         (= k :when) [false `(if ~v
                                               (do
                                                 ~subform
                                                 ~@(when needrec [recform]))
                                               ~recform)]))
                     (let [seq- (gensym &quot;seq_&quot;)
                           chunk- (with-meta (gensym &quot;chunk_&quot;)
                                             {:tag 'clojure.lang.IChunk})
                           count- (gensym &quot;count_&quot;)
                           i- (gensym &quot;i_&quot;)
                           in-chunk- (gensym &quot;in-chunk_&quot;)
                           recform `(if ~in-chunk-
                                      (recur ~seq- ~chunk- ~count- (unchecked-inc ~i-))
                                      (recur (next ~seq-) nil 0 0))
                           steppair (step recform (nnext exprs))
                           needrec (steppair 0)
                           subform (steppair 1)]
                       [true
                        `(loop [~seq- (seq ~v), ~chunk- nil,
                                ~count- 0, ~i- 0]
                           (let [~in-chunk- (&amp;lt; ~i- ~count-)
                                 ~seq- (if ~in-chunk- ~seq- (seq ~seq-))]
                             (when (if ~in-chunk- true ~seq-)
                               (let [chunked?# (if ~in-chunk- false (chunked-seq? ~seq-))
                                     ~k (if ~in-chunk-
                                          (.nth ~chunk- ~i-)
                                          (if chunked?# nil (first ~seq-)))]
                                 (if (if ~in-chunk- false chunked?#)
                                   (let [c# (chunk-first ~seq-)]
                                     (recur (chunk-rest ~seq-) c#
                                            (int (count c#)) (int 0)))
                                   (do ~subform
                                       ~@(when needrec [recform])))))))])))))]
    (nth (step nil (seq seq-exprs)) 1)))
&lt;/code&gt;&lt;/pre&gt;
</description>
<category>Macros</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/14433/doseq-and-for-expands-body-twice?show=14433#q14433</guid>
<pubDate>Wed, 05 Mar 2025 18:46:18 +0000</pubDate>
</item>
<item>
<title>Answer selected: defn rejects arity with args vector [&amp;form]</title>
<link>https://ask.clojure.org/index.php/14057/defn-rejects-arity-with-args-vector-form?show=14073#a14073</link>
<description>&lt;p&gt;Logged as &lt;a rel=&quot;nofollow&quot; href=&quot;https://clojure.atlassian.net/browse/CLJ-2874&quot;&gt;https://clojure.atlassian.net/browse/CLJ-2874&lt;/a&gt;&lt;/p&gt;
</description>
<category>Macros</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/14057/defn-rejects-arity-with-args-vector-form?show=14073#a14073</guid>
<pubDate>Thu, 22 Aug 2024 20:36:01 +0000</pubDate>
</item>
<item>
<title>Commented: Returning the last assigned value from `let` w/o a body</title>
<link>https://ask.clojure.org/index.php/13782/returning-the-last-assigned-value-from-let-w-o-a-body?show=13784#c13784</link>
<description>Probably also worth mentioning that the body of a let is wrapped in an implicit do, so (let [x 1 y 2]) is really equivalent to (let [x 1 y 2] (do)) and (do) is going to return nil</description>
<category>Macros</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/13782/returning-the-last-assigned-value-from-let-w-o-a-body?show=13784#c13784</guid>
<pubDate>Thu, 14 Mar 2024 00:21:50 +0000</pubDate>
</item>
<item>
<title>Commented: Auto-gensym in recursive macros</title>
<link>https://ask.clojure.org/index.php/12012/auto-gensym-in-recursive-macros?show=13573#c13573</link>
<description>this sounds like more a problem with your transpiler?&lt;br /&gt;
&lt;br /&gt;
If you are operating on clojure source and compiling to java, well clojure allows for the same named to be bound in nested static scopes, you you'll have to deal with it via something like alpha conversion.&lt;br /&gt;
&lt;br /&gt;
If you are decompiling jvm byte code to java, the jvm doesn't actually name locals at all, they just get numbered slows. The names are stored as optional debug information, and there is no requirement for uniqueness &lt;a href=&quot;https://docs.oracle.com/javase/specs/jvms/se11/html/jvms-4.html#jvms-4.7.13&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;https://docs.oracle.com/javase/specs/jvms/se11/html/jvms-4.html#jvms-4.7.13&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
So in either case to faithful capture the semantics (clojure-&amp;gt;java, jvm bytecode-&amp;gt;java) you need to be able to deal with possibly duplicate names</description>
<category>Macros</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/12012/auto-gensym-in-recursive-macros?show=13573#c13573</guid>
<pubDate>Mon, 18 Dec 2023 21:15:14 +0000</pubDate>
</item>
<item>
<title>Commented: Useful macro for output redirection (feature request)</title>
<link>https://ask.clojure.org/index.php/13246/useful-macro-for-output-redirection-feature-request?show=13277#c13277</link>
<description>Agree.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
P.S.: I cannot send messages shorter than 12 chars lol</description>
<category>Macros</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/13246/useful-macro-for-output-redirection-feature-request?show=13277#c13277</guid>
<pubDate>Tue, 12 Sep 2023 20:17:25 +0000</pubDate>
</item>
<item>
<title>Commented: Macro does not work properly</title>
<link>https://ask.clojure.org/index.php/13127/macro-does-not-work-properly?show=13131#c13131</link>
<description>You are correct, thank you! I forgot that Clojure does not have cons cells.</description>
<category>Macros</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/13127/macro-does-not-work-properly?show=13131#c13131</guid>
<pubDate>Thu, 03 Aug 2023 21:47:56 +0000</pubDate>
</item>
<item>
<title>Commented: Why functions which are used inside macro do not evaluate their arguments before executing?</title>
<link>https://ask.clojure.org/index.php/13123/functions-which-inside-evaluate-arguments-before-executing?show=13126#c13126</link>
<description>Thank you very much!</description>
<category>Macros</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/13123/functions-which-inside-evaluate-arguments-before-executing?show=13126#c13126</guid>
<pubDate>Tue, 01 Aug 2023 22:38:27 +0000</pubDate>
</item>
<item>
<title>Retagged: Using literal map as a dispatch fn in defmulti</title>
<link>https://ask.clojure.org/index.php/12920/using-literal-map-as-a-dispatch-fn-in-defmulti?show=12920#q12920</link>
<description>&lt;p&gt;I discovered a minor edge case with the &lt;code&gt;defmulti&lt;/code&gt; macro when attempting to use a literal map as the dispatch-fn:&lt;br&gt;
&lt;code&gt;(defmulti frob {:dispatch :map})&lt;/code&gt;&lt;br&gt;
According to its arglist, the &lt;code&gt;attr-map?&lt;/code&gt; argument is optional, so the map should be parsed as its compulsory &lt;code&gt;dispatch-fn&lt;/code&gt;. Instead it is taken to be the var metadata map, and the function is set to &lt;code&gt;nil&lt;/code&gt;.&lt;br&gt;
&lt;code&gt;(frob :dispatch)
;; =&amp;gt; Execution error (NullPointerException) at scratch/eval68113 (REPL:169).
;;    Cannot invoke &quot;clojure.lang.IFn.invoke(Object)&quot; because &quot;this.dispatchFn&quot; is null&lt;/code&gt;&lt;br&gt;
Obviously using maps to dispatch a multimethod is not very sensible (amounting to a closed translation map from arg-&amp;gt;dispatch value), but it might be a case to consider.&lt;/p&gt;
</description>
<category>Macros</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/12920/using-literal-map-as-a-dispatch-fn-in-defmulti?show=12920#q12920</guid>
<pubDate>Tue, 30 May 2023 16:48:17 +0000</pubDate>
</item>
<item>
<title>Answered: filter with multiple lists on params</title>
<link>https://ask.clojure.org/index.php/12793/filter-with-multiple-lists-on-params?show=12797#a12797</link>
<description>&lt;p&gt;Most preds used with filter take one arg, so this is not commonly needed.&lt;/p&gt;
</description>
<category>Macros</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/12793/filter-with-multiple-lists-on-params?show=12797#a12797</guid>
<pubDate>Wed, 22 Mar 2023 19:58:57 +0000</pubDate>
</item>
<item>
<title>Closed: Bug (?) in with-open macro</title>
<link>https://ask.clojure.org/index.php/11447/bug-in-with-open-macro?show=11447#q11447</link>
<description>&lt;p&gt;I've noticed something strange when macroexpanding &lt;code&gt;(with-open ...)&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;(finally ...)&lt;/code&gt; part looks something like this: &lt;br&gt;
&lt;code&gt;(finally (. stream clojure.core/close))&lt;/code&gt;  &lt;/p&gt;
&lt;p&gt;While this code does work, it just doesn't feel right to me. &lt;br&gt;
I assume that, if, at some point in the future, the functin &lt;code&gt;clojure.core/close&lt;/code&gt; is added to the core namespace, it might break.&lt;/p&gt;
&lt;p&gt;Am I right or, maybe, the fact that  the method &lt;code&gt;close&lt;/code&gt; got namespace-qualified is irrelevant since any functio that goes inside the  dot special form invocation &lt;code&gt;(. object method)&lt;/code&gt; will be trated as a method name, regardless of its namespace?  &lt;/p&gt;
</description>
<category>Macros</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/11447/bug-in-with-open-macro?show=11447#q11447</guid>
<pubDate>Wed, 08 Mar 2023 16:01:55 +0000</pubDate>
</item>
<item>
<title>Answer selected: Access object field in macro without reflection</title>
<link>https://ask.clojure.org/index.php/12316/access-object-field-in-macro-without-reflection?show=12317#a12317</link>
<description>&lt;p&gt;The &lt;code&gt;^&lt;/code&gt; reader does not resolve symbols and accepts symbols and strings as tags (&lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/clojure/clojure/blob/0035cd8d73517e7475cb8b96c7911eb0c43a1a9d/src/jvm/clojure/lang/LispReader.java#L955-L956&quot;&gt;impl&lt;/a&gt;). &lt;br&gt;
Consequently, the compiler doesn't look at anything but symbols and strings (&lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/clojure/clojure/blob/0035cd8d73517e7475cb8b96c7911eb0c43a1a9d/src/jvm/clojure/lang/Compiler.java#L7556-L7563&quot;&gt;impl&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;With that being said, there's no warning if you preface &lt;code&gt;MyObj&lt;/code&gt; in &lt;code&gt;{:tag MyObj}&lt;/code&gt; with a syntax quote.&lt;/p&gt;
</description>
<category>Macros</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/12316/access-object-field-in-macro-without-reflection?show=12317#a12317</guid>
<pubDate>Tue, 18 Oct 2022 12:47:40 +0000</pubDate>
</item>
<item>
<title>Answer selected: Would a generalized some-&gt; macro be useful?</title>
<link>https://ask.clojure.org/index.php/12272/would-a-generalized-some-macro-be-useful?show=12280#a12280</link>
<description>&lt;p&gt;Logged as &lt;a rel=&quot;nofollow&quot; href=&quot;https://clojure.atlassian.net/browse/CLJ-2732&quot;&gt;https://clojure.atlassian.net/browse/CLJ-2732&lt;/a&gt;&lt;/p&gt;
</description>
<category>Macros</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/12272/would-a-generalized-some-macro-be-useful?show=12280#a12280</guid>
<pubDate>Mon, 03 Oct 2022 16:50:39 +0000</pubDate>
</item>
<item>
<title>Closed: Hash collisions in case statements try to evaluate the constants</title>
<link>https://ask.clojure.org/index.php/11395/hash-collisions-case-statements-try-evaluate-the-constants?show=11395#q11395</link>
<description>&lt;p&gt;When &lt;code&gt;case&lt;/code&gt; statements use hashing and have a hash collision, they embed a &lt;code&gt;condp&lt;/code&gt; expression. However, this expression inserts the constants directly, without quoting. If any constants include a symbol, then these will lead to an error.&lt;/p&gt;
&lt;p&gt;For example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(case 'a #{a} 1 :foo 2 a 3)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Leads to: &lt;code&gt;Unable to resolve symbol: a in this context&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;This can be seen when expanding the macro:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(macroexpand '(case 'a #{a} 1 :foo 2 a 3))
(let* [G__151 (quote a)] (case* G__151 0 1 (throw (java.lang.IllegalArgumentException. (clojure.core/str &quot;No matching clause: &quot; G__151))) {0 [-1640525200 (clojure.core/condp clojure.core/= G__151 #{a} 1 a 3 (throw (java.lang.IllegalArgumentException. (clojure.core/str &quot;No matching clause: &quot; G__151))))], 1 [:foo 2]} :compact :hash-equiv #{0}))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This shows a call to &lt;code&gt;case*&lt;/code&gt;. The first and second arguments are 0, 1. When these are used with &lt;code&gt;clojure.core/shift-mask&lt;/code&gt; both &lt;code&gt;'#{a}&lt;/code&gt; and &lt;code&gt;'a&lt;/code&gt; will hash to &lt;code&gt;0&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The 5th argument contains a map of hash codes to values, which contains:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{0 [-1640525200 (clojure.core/condp clojure.core/= G__151
                  #{a} 1
                  a 3
                  (throw (java.lang.IllegalArgumentException. (clojure.core/str &quot;No matching clause: &quot; G__151))))],
 1 [:foo 2]}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This &lt;code&gt;condp&lt;/code&gt; block contains unquoted values for &lt;code&gt;#{a}&lt;/code&gt; and &lt;code&gt;a&lt;/code&gt;, so they will incorrectly attempt to match on the value of the current binding for &lt;code&gt;a&lt;/code&gt; (if such a binding exists).&lt;/p&gt;
&lt;p&gt;Since &lt;code&gt;case&lt;/code&gt; will interpret every test-constant as a literal (explicitly stating that they need not be quoted), these values should be quoted when they appear in an embedded Clojure expression like this this &lt;code&gt;condp&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The following is a suggested patch to correct the generated code:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;diff --git a/src/clj/clojure/core.clj b/src/clj/clojure/core.clj
index 0dba6fcd..b21d4556 100644
--- a/src/clj/clojure/core.clj
+++ b/src/clj/clojure/core.clj
@@ -6690,7 +6690,7 @@ fails, attempts to require sym's namespace and retries.&quot;
                       (next ks) (next vs))
                     m))
         assoc-multi (fn [m h bucket]
-                      (let [testexprs (apply concat bucket)
+                      (let [testexprs (mapcat (fn [kv] [(list 'quote (first kv)) (second kv)]) bucket)
                             expr `(condp = ~expr-sym ~@testexprs ~default)]
                         (assoc m h expr)))
         hmap (reduce1
diff --git a/test/clojure/test_clojure/control.clj b/test/clojure/test_clojure/control.clj
index 92846ad3..f3fe436b 100644
--- a/test/clojure/test_clojure/control.clj
+++ b/test/clojure/test_clojure/control.clj
@@ -421,7 +421,14 @@
          :b 1
          :c -2
          :d 4294967296
-         :d 3))
+         :d 3)
+    (are [result input] (= result (case input
+                                    #{a} :set
+                                    :foo :keyword
+                                    a :symbol))
+         :symbol 'a
+         :keyword :foo
+         :set '#{a}))
   (testing &quot;test warn for hash collision&quot;
     (should-print-err-message
      #&quot;Performance warning, .*:\d+ - hash collision of some case test constants; if selected, those entries will be tested sequentially..*\r?\n&quot;
&lt;/code&gt;&lt;/pre&gt;
</description>
<category>Macros</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/11395/hash-collisions-case-statements-try-evaluate-the-constants?show=11395#q11395</guid>
<pubDate>Thu, 13 Jan 2022 22:05:35 +0000</pubDate>
</item>
<item>
<title>Commented: Macroexpanding a macro with `fn` crashes with &quot;fn did not conform to spec&quot;</title>
<link>https://ask.clojure.org/index.php/11449/macroexpanding-macro-with-crashes-with-did-not-conform-spec?show=11470#c11470</link>
<description>I see thanks again</description>
<category>Macros</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/11449/macroexpanding-macro-with-crashes-with-did-not-conform-spec?show=11470#c11470</guid>
<pubDate>Tue, 11 Jan 2022 23:07:54 +0000</pubDate>
</item>
<item>
<title>Commented: Macro defining function</title>
<link>https://ask.clojure.org/index.php/10911/macro-defining-function?show=10995#c10995</link>
<description>Indeed thanks so much! This is just an exercise from Brave clojure...</description>
<category>Macros</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/10911/macro-defining-function?show=10995#c10995</guid>
<pubDate>Mon, 30 Aug 2021 19:53:54 +0000</pubDate>
</item>
<item>
<title>Commented: Macro for threading lambda expression</title>
<link>https://ask.clojure.org/index.php/10749/macro-for-threading-lambda-expression?show=10752#c10752</link>
<description>I don't think there's any interest in adding this to Clojure itself. But the cool thing about Clojure and Lisps is we can all have our preferred syntax. :)</description>
<category>Macros</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/10749/macro-for-threading-lambda-expression?show=10752#c10752</guid>
<pubDate>Sat, 03 Jul 2021 14:58:31 +0000</pubDate>
</item>
<item>
<title>Commented: when-seq and if-seq as short-hand macros</title>
<link>https://ask.clojure.org/index.php/10450/when-seq-and-if-seq-as-short-hand-macros?show=10475#c10475</link>
<description>The name follows prior naming of `if-some`. Instead of `some?` we use the predicate `seq`.&lt;br /&gt;
To follow the behavior of `if-some` the binding should maybe not contain the `seq`-ed object, but the original object. This would also preserve the type information like @eval suggested.</description>
<category>Macros</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/10450/when-seq-and-if-seq-as-short-hand-macros?show=10475#c10475</guid>
<pubDate>Tue, 13 Apr 2021 09:58:06 +0000</pubDate>
</item>
<item>
<title>Answered: macroexpansion of macro with anonymous function argument</title>
<link>https://ask.clojure.org/index.php/10269/macroexpansion-of-macro-with-anonymous-function-argument?show=10270#a10270</link>
<description>&lt;p&gt;Try:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(macroexpand-1 '(func-macro (fn [x] x)))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;with a normal single quote instead. You don't need the backtick here.&lt;/p&gt;
</description>
<category>Macros</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/10269/macroexpansion-of-macro-with-anonymous-function-argument?show=10270#a10270</guid>
<pubDate>Sun, 28 Feb 2021 10:04:43 +0000</pubDate>
</item>
<item>
<title>Commented: Capture code as list</title>
<link>https://ask.clojure.org/index.php/10077/capture-code-as-list?show=10088#c10088</link>
<description>I finally have &amp;nbsp;this&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;(deftype Call [code])&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;(defn call*&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;[code]&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;(Call. code))&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;(def ^:private gen-sym-var&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;(let [f (.getDeclaredField clojure.lang.LispReader&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;GENSYM_ENV&amp;quot;)]&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;(.setAccessible f true)&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;(.get f nil)))&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;(def ^:private syntax-quote&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;(let [m (.getDeclaredMethod clojure.lang.LispReader$SyntaxQuoteReader&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;syntaxQuote&amp;quot; (into-array Class [Object]))]&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;(.setAccessible m true)&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;(fn [form]&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;(try&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;(clojure.lang.Var/pushThreadBindings (hash-map gen-sym-var {}))&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;(.invoke m nil (into-array Object [form]))&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;(finally&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;(clojure.lang.Var/popThreadBindings))))))&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;(defmacro &amp;nbsp;call&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;[&amp;amp; body]&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;(let [ks (set (keys &amp;amp;env))&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;myvar (walk/postwalk&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;(fn [sexp]&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;(if (contains? ks sexp)&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;(list 'clojure.core/unquote sexp)&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;sexp))&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;body)]&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;`(call* ~(syntax-quote myvar))))&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;(defn test&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;[p]&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;(let [n 1&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;^io.github.fp7.statem.Call foo (call n '(foo bar) (+ n 2) p)]&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;(.code foo)))&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;(test &amp;quot;&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
It works but calls internal methods of clojure. &amp;nbsp;So i think i will stick to my manual quoting/unquoting for the time being. I also tried the same thing with backtick, but that threw some null pointers.&lt;br /&gt;
&lt;br /&gt;
Thanks for your help!</description>
<category>Macros</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/10077/capture-code-as-list?show=10088#c10088</guid>
<pubDate>Sun, 24 Jan 2021 11:38:00 +0000</pubDate>
</item>
<item>
<title>Answer selected: Using atoms inside macro</title>
<link>https://ask.clojure.org/index.php/9339/using-atoms-inside-macro?show=9340#a9340</link>
<description>&lt;p&gt;Macros are functions that take code and return code. Atoms are stateful objects - there is no way to represent them with identity  in code so this is not going to work.&lt;/p&gt;
&lt;p&gt;What are you actually trying to do?&lt;/p&gt;
</description>
<category>Macros</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/9339/using-atoms-inside-macro?show=9340#a9340</guid>
<pubDate>Sun, 31 May 2020 19:44:01 +0000</pubDate>
</item>
<item>
<title>Answer selected: binding macro wraps body in try, not do</title>
<link>https://ask.clojure.org/index.php/9052/binding-macro-wraps-body-in-try-not-do?show=9053#a9053</link>
<description>&lt;p&gt;&lt;code&gt;try&lt;/code&gt; has an implicit &lt;code&gt;do&lt;/code&gt; in it - what do you want to do that doesn't work?&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(binding []
  (println &quot;1&quot;)
  (println &quot;2&quot;)
  3)
;; 1
;; 2
;;=&amp;gt; 3
&lt;/code&gt;&lt;/pre&gt;
</description>
<category>Macros</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/9052/binding-macro-wraps-body-in-try-not-do?show=9053#a9053</guid>
<pubDate>Tue, 21 Jan 2020 21:59:02 +0000</pubDate>
</item>
<item>
<title>Answer selected: Macros and dynamic vars</title>
<link>https://ask.clojure.org/index.php/8913/macros-and-dynamic-vars?show=8914#a8914</link>
<description>&lt;p&gt;&lt;code&gt;binding&lt;/code&gt; affects &lt;em&gt;runtime&lt;/em&gt;. Macros are generally expanded at read time. When you use &lt;code&gt;macroexpand&lt;/code&gt;, you are explicitly expanding the macro as part of runtime operations (so the &lt;code&gt;binding&lt;/code&gt; affects it).&lt;/p&gt;
</description>
<category>Macros</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/8913/macros-and-dynamic-vars?show=8914#a8914</guid>
<pubDate>Sun, 01 Dec 2019 23:09:28 +0000</pubDate>
</item>
<item>
<title>Answered: clojure.walk.macroexpand-all will not properly expand macros that depend on &amp;env</title>
<link>https://ask.clojure.org/index.php/1155/clojure-walk-macroexpand-will-properly-expand-macros-depend?show=1301#a1301</link>
<description>Reference: &lt;a href=&quot;https://clojure.atlassian.net/browse/CLJ-2011&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;https://clojure.atlassian.net/browse/CLJ-2011&lt;/a&gt; (reported by alex+import)</description>
<category>Macros</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/1155/clojure-walk-macroexpand-will-properly-expand-macros-depend?show=1301#a1301</guid>
<pubDate>Wed, 26 Jun 2019 12:00:00 +0000</pubDate>
</item>
<item>
<title>Answered: Macros cannot reliably detect usage of locals</title>
<link>https://ask.clojure.org/index.php/2814/macros-cannot-reliably-detect-usage-of-locals?show=3210#a3210</link>
<description>Reference: &lt;a href=&quot;https://clojure.atlassian.net/browse/CLJ-1997&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;https://clojure.atlassian.net/browse/CLJ-1997&lt;/a&gt; (reported by gfredericks)</description>
<category>Macros</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/2814/macros-cannot-reliably-detect-usage-of-locals?show=3210#a3210</guid>
<pubDate>Wed, 26 Jun 2019 12:00:00 +0000</pubDate>
</item>
</channel>
</rss>