<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0">
<channel>
<title>Clojure Q&amp;A - Recent questions tagged optimization</title>
<link>https://ask.clojure.org/index.php/tag/optimization</link>
<description></description>
<item>
<title>Possibly avoidable identity call to force instance method on Class literals</title>
<link>https://ask.clojure.org/index.php/15155/possibly-avoidable-identity-force-instance-method-literals</link>
<description>&lt;p&gt;As of Clojure 1.13.0-alpha2, &lt;code&gt;(.method ClassName)&lt;/code&gt; expands to &lt;code&gt;(.method ^Class (identity ClassName))&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;This is to force &lt;code&gt;(.method ClassName)&lt;/code&gt; to always be an instance method. Without this, it would expand to &lt;code&gt;(. ClassName method)&lt;/code&gt;, which may instead be interpreted as a static method.&lt;/p&gt;
&lt;p&gt;For example, &lt;code&gt;(.getMethods String)&lt;/code&gt; expands to &lt;code&gt;(.getMethods ^Class (identity String))&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;This was introduced in these two commits:&lt;br&gt;
- &lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/clojure/clojure/commit/f95175264df36c3d8fe2113aa9af92cda0f2f5c8&quot;&gt;force instance member interpretation of (.method ClassName), e.g. (.getMethods String) works&lt;/a&gt;&lt;br&gt;
- &lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/clojure/clojure/commit/e45046da8f7fef82157b58af54d1ac6de8e31160&quot;&gt;added autohinting to Class in macroexpansion of (.instanceMethodOfClass Classname) calls&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Since then, Clojure has added support for qualified methods which we can use to reliably propagate the tag without any runtime changes. For example, expanding to &lt;code&gt;(Class/.getMethods String)&lt;/code&gt; is now equivalent to &lt;code&gt;(.getMethods ^Class (identity String))&lt;/code&gt; in terms of tag propagation.&lt;/p&gt;
&lt;p&gt;I have a proof-of-concept &lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/frenchy64/clojure/pull/52/changes&quot;&gt;here&lt;/a&gt; that includes disassembled and decompiled output before and after the change. The net effect of using qualified methods in this case under direct linking is a removal of a single method call to &lt;code&gt;identity&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;   3: invokestatic  #20                 // Method clojure/core$identity.invokeStatic:(Ljava/lang/Object;)Ljava/lang/Object;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The effect is more substantial without direct linking (not included in the PR), with &lt;code&gt;clojure.core/identity&lt;/code&gt; also being added to the static initializer.&lt;/p&gt;
&lt;p&gt;I've also experimented with expanding to &lt;code&gt;(. (do String) getMethods)&lt;/code&gt; (see earlier commits in that PR), which seems to also work and might be another approach.&lt;/p&gt;
</description>
<category>Compiler</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/15155/possibly-avoidable-identity-force-instance-method-literals</guid>
<pubDate>Thu, 02 Jul 2026 23:47:10 +0000</pubDate>
</item>
<item>
<title>Why does an atom not implemented the &quot;ISwap&quot; protocol?</title>
<link>https://ask.clojure.org/index.php/9291/why-does-an-atom-not-implemented-the-iswap-protocol</link>
<description>&lt;p&gt;Why does an atom &lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/clojure/clojurescript/blob/master/src/main/cljs/cljs/core.cljs#L4431-L4458&quot;&gt;not implemented&lt;/a&gt; the &quot;ISwap&quot; protocol?  &lt;/p&gt;
&lt;p&gt;It's the &lt;code&gt;swap!&lt;/code&gt; &lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/clojure/clojurescript/blob/master/src/main/cljs/cljs/core.cljs#L4510-L4530&quot;&gt;implementation&lt;/a&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(defn swap!
  ([a f]
   (if (instance? Atom a)
     (reset! a (f (.-state a)))
     (-swap! a f))))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It's not about optimization because GCC does not inline the &lt;code&gt;swap!&lt;/code&gt; call.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;;; clj -m cljs.main --optimizations advanced -co '{:pseudo-names true}' -c example.core

(let [a (atom 0)]
  (swap! a inc)
  (js/console.log @a))

var $a_528$$ = new $cljs$core$Atom$$;
$cljs$core$swap_BANG_$$.$cljs$core$IFn$_invoke$arity$2$($a_528$$, function($x$jscomp$125$$) {
    return $x$jscomp$125$$ + 1
});
console.log($cljs$core$_deref$$($a_528$$));
&lt;/code&gt;&lt;/pre&gt;
</description>
<category>ClojureScript</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/9291/why-does-an-atom-not-implemented-the-iswap-protocol</guid>
<pubDate>Wed, 06 May 2020 18:19:56 +0000</pubDate>
</item>
</channel>
</rss>