This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2023-12-06
Channels
- # adventofcode (54)
- # announcements (3)
- # babashka (34)
- # beginners (38)
- # calva (27)
- # cherry (5)
- # clj-kondo (34)
- # clojure (26)
- # clojure-bay-area (4)
- # clojure-berlin (3)
- # clojure-europe (26)
- # clojure-india (6)
- # clojure-nl (1)
- # clojure-norway (54)
- # clojure-uk (2)
- # conjure (3)
- # cursive (4)
- # data-science (1)
- # emacs (6)
- # events (4)
- # fulcro (2)
- # hugsql (6)
- # hyperfiddle (38)
- # lsp (3)
- # matrix (1)
- # membrane (5)
- # off-topic (27)
- # re-frame (3)
- # releases (1)
- # sci (8)
- # shadow-cljs (34)
- # squint (132)
I have a macro letm
that looks like let
but returns all the defined bindings as a map. If I lint it as let
, it then reports unused-bindings in it as in the following example:
(is (= {:x 5} (letm [x 5])))
Is it possible to configure unused-bindings to be disabled inside the body of letm
?
I was able to achieve this with {:config-in-call {letm {:linters {:unused-binding {:level :off}}}}
config but I found that it applies to all nested structures. So for example the following unused z
won’t be reported:
(println (letm [x (let [z 1] 5)]))
Is it possible to have a narrower focus of a config-in-call
rule so that it doesn’t report x
as unused but reports z
as such?
One possible solution might be to create a hook the prepends every variable definition inside the binding with #_{:clj-kondo/ignore [:unused-binding]}
as in (let [#_{:clj-kondo/ignore [:unused-binding]} x (let [z 1] 5)])
but I do not see how that can be created with rewrite-clj. Am I missing anything?Try a hook that expands to a let and then returns a vector of all of the variables
So expand to (let [z 1 a 2 b 3] [z a b <actual return value>])
Or (let [z 1 a 2 b 3] [z a b] <actual return value>)
given:
(defmacro letm [bindings]
(let [ks (take-nth 2 bindings)
kws (mapv keyword ks)]
`(let ~bindings
(hash-map ~@(mapcat vector ks kws)))))
(letm [a 1 b 2 c (+ a b)])
using :macroexpand
config, this works;
(defmacro letm
[bindings]
(let [ks (take-nth 2 bindings)
kws (mapv keyword ks)]
`(let ~bindings
(hash-map ~@(mapcat vector ks kws)))))
I’ve used a more decomplected macro in the past which just captured locals by name as a map: (->m a b c), it didn’t need any kondo config, also no unused binding
that's not exactly the same as letm
. might still be useful
It’s not the same, it’s more decomplected as I said. It composes with existing let and fn bindings and lets you capture only the binding you want and not any auxiliary bindings
> Try a hook that expands to a let and then returns a vector of all of the variables > Why not rewrite it to the actual expansion? Given that let allows a number of destructuring options, figuring out every symbol I need to rewrite to doesn’t look easy. Consider these examples;
(letm [[x {:keys [y] b :b}] val])
> Or use lint-as let
lint-as
reports unused bindings.
Am I correct that the suggestion is to use the macroexpand
hook with pretty much the original macro content?
Thanks! I’ll give it a try!
If that doesn’t work, i can try again but I’ll need to see the full macro
Do you know what kind of macros do not work with :macroexpand
hooks?
This letm
macro implementation is calling destructure
function from clojure.core
before generating the nodes and it looks like that is an unsupported external dependency.
I was afraid you might say that
I just wired up clj-kondo to my cljs project and I’m noticing that it can’t resolve args in my re-frame event handlers, e.g.
(reg-event-fx ::close-work
(fn-traced [{:keys [db]} [_ {:keys [navigate]}]]
{:dispatch-debounce {:id :info-update :action :flush}
:navigate navigate}))
it (rightly, I suppose) can’t resolve db or navigate..
Is there a way to tell it to ignore resolving them? FWIW, I have same problem in cursive’s built in checking and its a bit annoyingI don't know where fn-traced is coming from, but that would probably be the solution
So is that something I can put in the .clj-kondo file? first time using it so very green 🙂