<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0">
<channel>
<title>Clojure Q&amp;A - Recent questions tagged protocols</title>
<link>https://ask.clojure.org/index.php/tag/protocols</link>
<description></description>
<item>
<title>Missing protocol error will hang on infinite `(range)` input in ClojureScript but not Clojure</title>
<link>https://ask.clojure.org/index.php/15026/missing-protocol-error-infinite-range-clojurescript-clojure</link>
<description>&lt;p&gt;functions like &lt;code&gt;transient&lt;/code&gt;, &lt;code&gt;assoc&lt;/code&gt;, etc  will throw helpful missing-protocol error when receiving invalid input but it will hang if it receives infinite &lt;code&gt;(range)&lt;/code&gt;.&lt;br&gt;
this is related to issue below&lt;br&gt;
&lt;a rel=&quot;nofollow&quot; href=&quot;https://ask.clojure.org/index.php/14578/even-range-hangs?show=14578#q14578&quot;&gt;https://ask.clojure.org/index.php/14578/even-range-hangs?show=14578#q14578&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;however, missing-protocol only hang in clojurescript but not clojure so I am wondering if this difference is intended.&lt;/p&gt;
&lt;p&gt;example calls that should throws&lt;br&gt;
- &lt;code&gt;(transient (range))&lt;/code&gt;&lt;br&gt;
- &lt;code&gt;(assoc (range) :a 1)&lt;/code&gt;&lt;/p&gt;
</description>
<category>ClojureScript</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/15026/missing-protocol-error-infinite-range-clojurescript-clojure</guid>
<pubDate>Fri, 03 Apr 2026 11:16:47 +0000</pubDate>
</item>
<item>
<title>An undocumented breaking change in data.json</title>
<link>https://ask.clojure.org/index.php/14728/an-undocumented-breaking-change-in-data-json</link>
<description>&lt;p&gt;between the versions &lt;code&gt;1.1.0&lt;/code&gt; and &lt;code&gt;2.0.0&lt;/code&gt;, data.json introduced a breaking change: The &lt;code&gt;JSONWriter#-write&lt;/code&gt; signature changed from &lt;code&gt;[object out]&lt;/code&gt; to &lt;code&gt;[object out options]&lt;/code&gt;&lt;br&gt;
On this commit:&lt;br&gt;
&lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/clojure/data.json/commit/8f070ba94dc7c469f303259ce5f5bfa0b53d50bd&quot;&gt;https://github.com/clojure/data.json/commit/8f070ba94dc7c469f303259ce5f5bfa0b53d50bd&lt;/a&gt;&lt;br&gt;
In release notes &lt;code&gt;Release 2.0.0 on 2021-Mar-19 &lt;/code&gt;, there is no mention to &lt;code&gt;JSONWriter&lt;/code&gt; or &lt;code&gt;-write&lt;/code&gt; protocol changes.&lt;/p&gt;
&lt;p&gt;I know it's a very old problem, but I think this documentation could be present.&lt;/p&gt;
</description>
<category>data.json</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/14728/an-undocumented-breaking-change-in-data-json</guid>
<pubDate>Thu, 23 Oct 2025 17:18:23 +0000</pubDate>
</item>
<item>
<title>Protocol function with placeholder _ arguments doesn't work as in Clojure</title>
<link>https://ask.clojure.org/index.php/14469/protocol-function-with-placeholder-arguments-doesnt-clojure</link>
<description>&lt;p&gt;A protocol like below will work in Clojure without issue, but in ClojureScript the _'s will apparently (quietly) override each other left to right.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(defprotocol Linkable
  (-href [_ _ _]))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Even if the extend-protocol has unique names for the args, the dispatch seems to happen on the last argument.&lt;/p&gt;
&lt;p&gt;Repro at &lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/valerauko/proto-repro/commit/a8ad51a225ed44ed134b28a18cc83d272d0d8321&quot;&gt;https://github.com/valerauko/proto-repro/commit/a8ad51a225ed44ed134b28a18cc83d272d0d8321&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Using distinct argument names in the defprotocol solves the issue. I think if it doesn't / can't work like in JVM Clojure it should warn about this issue.&lt;/p&gt;
</description>
<category>ClojureScript</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/14469/protocol-function-with-placeholder-arguments-doesnt-clojure</guid>
<pubDate>Mon, 17 Mar 2025 14:58:32 +0000</pubDate>
</item>
<item>
<title>Hypergraphs, via protocols, perhaps extending loom?</title>
<link>https://ask.clojure.org/index.php/13444/hypergraphs-via-protocols-perhaps-extending-loom</link>
<description>&lt;p&gt;I am exploring clojure implementations of hypergraphs (edges can join &amp;gt; 2 nodes)?  i've used &lt;a rel=&quot;nofollow&quot; href=&quot;https://cljdoc.org/d/aysylu/loom&quot;&gt;loom&lt;/a&gt;  for graphs, and imagine trying to extend it somehow.  &lt;/p&gt;
&lt;p&gt;either with loom or without, any suggestions how to use PROTOCOLS for these definitions?&lt;/p&gt;
&lt;p&gt;thanks for any suggestions.  - RIk&lt;/p&gt;
</description>
<category>Protocols</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/13444/hypergraphs-via-protocols-perhaps-extending-loom</guid>
<pubDate>Thu, 09 Nov 2023 02:41:39 +0000</pubDate>
</item>
<item>
<title>Protocols and eager evaluation in partial</title>
<link>https://ask.clojure.org/index.php/13148/protocols-and-eager-evaluation-in-partial</link>
<description>&lt;p&gt;The bug &lt;a rel=&quot;nofollow&quot; href=&quot;https://clojure.atlassian.net/browse/CLJ-2094&quot;&gt;CLJ-2094&lt;/a&gt; demonstrates an edge case with protocols stemming from functions like &lt;code&gt;partial&lt;/code&gt; eagerly evaluating their arguments and thus retaining outdated references. I ran into this recently and found that the ticket had been declined because of &quot;normal Clojure evaluation rules&quot;.&lt;/p&gt;
&lt;p&gt;I think there's an easy fix for protocols that adds very little overhead and allows protocol-related functions to work in both eager and lazy evaluation contexts. Would the team be interested in a patch for this?&lt;/p&gt;
</description>
<category>Clojure</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/13148/protocols-and-eager-evaluation-in-partial</guid>
<pubDate>Tue, 08 Aug 2023 23:56:17 +0000</pubDate>
</item>
<item>
<title>Allow clojure.core/extend to take a regular map as proto+mmaps parameter (today it's just &quot;kwargs&quot;)</title>
<link>https://ask.clojure.org/index.php/12752/clojure-extend-regular-proto-mmaps-parameter-today-kwargs</link>
<description>&lt;p&gt;Often, when you call clojure.core/extend directly (vs extend-type, extend-proto or inline definitions), that means you have some level of composition that happened upstream to create proto extensions for a type. &lt;/p&gt;
&lt;p&gt;To recap today the signature of extend is as follows:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;([atype &amp;amp; proto+mmaps])
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Meaning when it's called it looks like &lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(extend t protoA {...} protoB {...})
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I am advocating to just changing it to &lt;/p&gt;
&lt;pre&gt;&lt;code&gt;([atype &amp;amp; {:as proto+mmaps}])
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;That would allow somebody calling into extend to pass either an &quot;unrolled&quot; map like today, or a regular map to it (leveraging the recent patch from @fogus).&lt;/p&gt;
&lt;p&gt;(extend t {protoA {...} protoB {...}}) and (extend t protoA {...} protoB {...}) would be supported. &lt;/p&gt;
&lt;p&gt;The alternative today when you have a proto+mmaps that is the result of merging implementations is to do something akin to:&lt;/p&gt;
&lt;p&gt;(apply extend t (into [] cat proto+mmaps))&lt;/p&gt;
&lt;p&gt;the patch would allow to do things such as:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(extend t (merge proto-impl-a proto-impl-b proto-impl-c ...))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I am happy to provide a patch for this if that's considered to be an acceptable change.&lt;/p&gt;
</description>
<category>Protocols</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/12752/clojure-extend-regular-proto-mmaps-parameter-today-kwargs</guid>
<pubDate>Sat, 11 Mar 2023 17:02:27 +0000</pubDate>
</item>
<item>
<title>Would it make sense to have a flag to cache protocol implementation lookups?</title>
<link>https://ask.clojure.org/index.php/11801/would-make-sense-have-cache-protocol-implementation-lookups</link>
<description>&lt;p&gt;In recent conversation I learned that some developers avoid and discourage the use of &lt;code&gt;satisfies?&lt;/code&gt; because of performance concerns. I was told to &quot;just look at the implementation, you will sweat bullets&quot;.&lt;/p&gt;
&lt;p&gt;The implementation in this case is in &lt;code&gt;find-protocol-impl&lt;/code&gt; which has to check metadata, traverse the inheritance chain as well as implemented interfaces.&lt;/p&gt;
&lt;p&gt;The part of finding a protocol implementation for a specific class seems emminently cacheable, except for the fact that one can extend the protocol later on.&lt;/p&gt;
&lt;p&gt;Would it make sense to cache this, and have &lt;code&gt;extend-*&lt;/code&gt; invalidate the cache? Or alternatively to have a flag (e.g. &lt;code&gt;-J-Dclojure.cache-protocols=true&lt;/code&gt;) for use in production where you know all protocol implementations will be loaded before lookups happen?&lt;/p&gt;
</description>
<category>Protocols</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/11801/would-make-sense-have-cache-protocol-implementation-lookups</guid>
<pubDate>Mon, 25 Apr 2022 13:02:50 +0000</pubDate>
</item>
<item>
<title>Emit named functions in protocols and extend macros</title>
<link>https://ask.clojure.org/index.php/11345/emit-named-functions-in-protocols-and-extend-macros</link>
<description>&lt;p&gt;Is it possible to add names to the functions emitted by defprotocol and the various extend-* macros?&lt;br&gt;
It would make anything involving stack traces, from exceptions to profiling, more informative&lt;/p&gt;
</description>
<category>Clojure</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/11345/emit-named-functions-in-protocols-and-extend-macros</guid>
<pubDate>Thu, 02 Dec 2021 18:55:01 +0000</pubDate>
</item>
<item>
<title>When does a metadata protocol extension get chosen?</title>
<link>https://ask.clojure.org/index.php/11085/when-does-a-metadata-protocol-extension-get-chosen</link>
<description>&lt;p&gt;It seems like a metadata protocol implementation overrides &lt;code&gt;extend&lt;/code&gt; calls, but not direct implementations. Is this expected? How does choosing a metadata protocol interact with the caching of defprotocol methods? Are there any other gotchas?&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Clojure 1.10 .3
user=&amp;gt; (defprotocol A :extend-via-metadata true (foo [this]))
A
user=&amp;gt; (defrecord Direct [] A (foo [_] :direct))
user.Direct
user=&amp;gt; (foo (-&amp;gt;Direct))
:direct
user=&amp;gt; (foo (with-meta (-&amp;gt;Direct) {`foo (fn [_] :meta)}))
:direct
user=&amp;gt; (defrecord Extend [])
user.Extend
user=&amp;gt; (extend-protocol A Extend (foo [_] :extend))
nil
user=&amp;gt; (foo (-&amp;gt;Extend))
:extend
user=&amp;gt; (foo (with-meta (-&amp;gt;Extend) {`foo (fn [_] :meta)}))
:meta
&lt;/code&gt;&lt;/pre&gt;
</description>
<category>Protocols</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/11085/when-does-a-metadata-protocol-extension-get-chosen</guid>
<pubDate>Wed, 22 Sep 2021 20:23:51 +0000</pubDate>
</item>
<item>
<title>Record refinement feature</title>
<link>https://ask.clojure.org/index.php/9953/record-refinement-feature</link>
<description>&lt;ol&gt;
&lt;li&gt;My project depends on library &quot;lib&quot;.&lt;/li&gt;
&lt;li&gt;This library has a protocol &lt;code&gt;lib.core/P&lt;/code&gt; with 10 functions and a record &lt;code&gt;lib.core/R&lt;/code&gt; implementing the protocol.&lt;/li&gt;
&lt;li&gt;In my project I need a record &lt;code&gt;my.core/Q&lt;/code&gt; that is a lot like R: out of the 10 functions just 1 is different.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;What are my options for implementing Q:&lt;br&gt;
a) &lt;strong&gt;Copy paste&lt;/strong&gt; the other 9 functions from R.&lt;br&gt;
b) What else?&lt;/p&gt;
&lt;p&gt;Would a &quot;record refinement&quot; feature of sorts be worthwhile?&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(defrecord Q [a b c]
  :refines lib.core/R
  lib.core/P
  (just-my-one-changed-fn [] ...))
&lt;/code&gt;&lt;/pre&gt;
</description>
<category>Records and Types</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/9953/record-refinement-feature</guid>
<pubDate>Sat, 19 Dec 2020 21:42:33 +0000</pubDate>
</item>
<item>
<title>Implementing a type or record to support defmethod in CLJ</title>
<link>https://ask.clojure.org/index.php/9045/implementing-a-type-or-record-to-support-defmethod-in-clj</link>
<description>&lt;p&gt;Thanks to &lt;code&gt;IMultiFn&lt;/code&gt; in CLJS types and records can be easily extended to behave as multimethods. For example:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;`&lt;/code&gt;(defrecord MyMulti&lt;br&gt;
  [add-method remove-method dispatch-fn method-table]&lt;br&gt;
  IMultiFn&lt;br&gt;
  (-add-method [_ dispatch-val f]&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(add-method dispatch-val f))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;  (-remove-method [_ dispatch-val]&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(remove-method dispatch-val))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;  (-methods [_] @method-table))&lt;/p&gt;
&lt;p&gt;(def my-multi (-&amp;gt;MyMulti ...))&lt;/p&gt;
&lt;p&gt;(defmethod my-multi :foo&lt;br&gt;
  [x]&lt;br&gt;
  ...)&lt;br&gt;
&lt;code&gt;`&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;In Clojure however this isn't as easy because multimethods are not implemented using protocols. IS there ANY way to make a record or type to work with defmethod in CLJ?&lt;/p&gt;
&lt;p&gt;Thanks!&lt;/p&gt;
</description>
<category>Multimethods</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/9045/implementing-a-type-or-record-to-support-defmethod-in-clj</guid>
<pubDate>Fri, 17 Jan 2020 18:37:33 +0000</pubDate>
</item>
</channel>
</rss>