cljs-dev 2026-07-06

Interesting difference between CLJS and Clojure:

$ clj
Clojure 1.12.1
user=> (counted? nil)
false
user=>

ClojureScript 1.12.145
cljs.user=> (counted? nil)
true

(defn counted?
 "Returns true if coll implements count in constant time"
 {:added "1.0"
   :static true}
  [coll] (instance? clojure.lang.Counted coll))
Counted would be so much cooler as a protocol rather than an interface. 🙂

There's plenty of specialized nil checks in core functions

ah, agreed 👍 - I don't know what it would break, but if (counted? nil) were true, that would make sense to me. (I can get you 0 in constant time).

(count nil) => 0

🆒 1

I did some research and apparently this behavior was introduced, or at least formalized, in this commit. It references the issue #23, that is not the github issue. Jira https://clojure.atlassian.net/browse/CLJS-23 seems that also do not exists. In other words, we don't have much context as to why this was done. https://github.com/clojure/clojurescript/commit/e32fde014e4aa2949e0665d83ca062189cba5cbe

Alex Miller (Clojure team) 2026-07-06T19:35:34.160369Z

there are a few places that branch on whether counted? for perf but I suspect the perf difference is negligible in the case of nil, so it doesn't really matter

Alex Miller (Clojure team) 2026-07-06T19:35:59.426859Z

empty? is the one that immediately comes to mind

Alex Miller (Clojure team) 2026-07-06T19:39:12.025439Z

might be the difference of taking 2 ns instead of 1 ns there for (empty? nil) (although you have to keep in mind the now slightly slower count? impl for every branch too)

Rich wrote the relevant code in 2011. I'm not sure about changing the semantics now since it seemed intentional. And yeah, I'm not sure how meaningful optimizing this is.