clojurescript

Jack Arrington 2026-05-27T07:03:24.388739Z

I write a lot of .cljc files, and I run into a problem where I have some refers at the top, some of which are only used in CLJ, some only in CLJS, and then that causes warnings about unused variables to show up.

(ns my.ns
  (:require [some.namespace :refer [used-in-clj-only ;; this will give a warning about an unused var in CLJS
                                    used-in-cljs-only ;; this will give a warning about an unused var in CLJ
                                    used-in-both-1
                                    used-in-both-2]]))
If I try to add a conditional it then complains about duplicate requires:
(ns my.ns
  (:require
   ;; Now this will complain of a duplicate :require
   #?(:clj  [some.namespace :refer [used-in-clj-only]]
      :cljs [some.namespace :refer [used-in-cljs-only]])
   [some.namespace :refer [used-in-both-1
                           used-in-both-2]]))
I'm sure I'm missing something simple here, what's the recommended way of dealing with this?

p-himik 2026-05-27T07:16:59.323149Z

The best solution here IMHO is to stop using :refer and use :as instead.

p-himik 2026-05-27T07:17:50.599609Z

It will also make the ns form smaller and more readable, will make any refactoring require fewer changes, will make it obvious where a symbol came from at the call site.

Jack Arrington 2026-05-27T07:21:27.446709Z

I would say that's a highly subjective definition of "best" 🙂. (I do, for the record, tend to prefer using :refer as little as possible. But sometimes the brevity is worth the tradeoff of being slightly less explicit.)

Jack Arrington 2026-05-27T07:22:02.312499Z

To each their own of course

p-himik 2026-05-27T07:22:11.181249Z

That's why the "IMHO". :) But also, this is pretty much as good as it gets in the context of the OP, with reader conditionals.

Jack Arrington 2026-05-27T07:23:07.281499Z

> But also, this is pretty much as good as it gets in the context of the OP, with reader conditionals. That surprises me...I would think this is a common enough need that there must be some solution

p-himik 2026-05-27T07:25:58.570239Z

Why is using :as not a solution?.. Oh, it also reduces the number of reader conditionals you have to use. Alternatively, you can wrap every single conditional item inside :refer [...] into its own reader conditional. And use a splicing reader conditional, something like [some.namespace :refer [#?@(:clj [clj-only1 clj-only2] :cljs [cljs-only1 cljs-only2]) common1 common2]]. But boy is that ugly. :D Just in case, a couple of things: • You don't even need to use :as, you can just require [some.namespace] and use it as some.namespace/... • Aliases can have dogs, so you can have [some.namespace :as some.ns]

p-himik 2026-05-27T07:27:26.124549Z

BTW this: >

;; Now this will complain of a duplicate :require
likely comes from your IDE or something else. Definitely not from Clojure itself. So maybe another solution here is to change the configuration of that something so it stops complaining.

borkdude 2026-05-27T12:29:22.170819Z

(ns my.ns
  (:require [some.namespace :refer [#?(:clj used-in-clj-only) ;; this will give a warning about an unused var in CLJS
                                    #?(:cljs used-in-cljs-only) ;; this will give a warning about an unused var in CLJ
                                    used-in-both-1
                                    used-in-both-2]]))
is what I would do. the comment behind it almost begs for it.

👍 2
Jack Arrington 2026-05-27T14:03:43.363269Z

@borkdude y'know it did not occur to me that that would work. But I guess it makes sense, a single form is a single form.

jlfischer 2026-05-27T20:30:18.461119Z

react