This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2023-12-14
Channels
- # adventofcode (29)
- # aws (3)
- # babashka (25)
- # beginners (13)
- # calva (4)
- # cherry (7)
- # cider (26)
- # clj-kondo (9)
- # clojure (88)
- # clojure-europe (21)
- # clojure-losangeles (3)
- # clojure-nl (1)
- # clojure-norway (6)
- # clojure-uk (11)
- # clojuredesign-podcast (2)
- # clojurescript (4)
- # cursive (10)
- # datalevin (1)
- # emacs (50)
- # gratitude (1)
- # honeysql (12)
- # hyperfiddle (19)
- # jobs-discuss (28)
- # kaocha (3)
- # lsp (53)
- # malli (4)
- # meander (3)
- # off-topic (48)
- # re-frame (11)
- # releases (2)
- # ring-swagger (2)
- # shadow-cljs (50)
- # squint (26)
- # tools-build (3)
- # tools-deps (8)
- # xtdb (4)
- # yamlscript (1)
Hey - I set up lsp in emacs and I am getting some warnings for unresolved var that are incorrect (the var is definitely resolved), and my code still compiles and runs. How do I fix/debug that?
Here's an example piece of code:
(ns undl-sync.state.redis
(:gen-class)
(:require
[taoensso.carmine :as carmine]))
(defn redis-key
"Computes the key for a given task"
[date [start end]]
(str date ":" start "-" end))
(def statuses {:initialized "INITIALIZED"
:assigned "ASSIGNED"
:downloaded "DOWNLOADED"
:failed-to-download "FAILED_TO_DOWNLOAD"
:completed "COMPLETED"})
(defonce conn-pool (carmine/connection-pool {}))
(def conn-spec {:uri ""})
(def car-opts {:pool conn-pool :spec conn-spec})
(defmacro wcar* [& body] `(carmine/wcar ~car-opts ~@body))
(defn set-state
"Sets the state of a work, defined by its date and range.
Expects an object with { :status state } at least, and potentially other metadata"
[date range status]
(let [work-status (:status status)
body (if (= work-status :downloaded) (str work-status (:file-size status))
work-status)
key (redis-key date range)]
(wcar* (carmine/set key body))))
LSP throws a warning on the final line, for (carmine/set), but on no other line, carmine-related or otherwise. Compiling works fine.Which var is it claiming is unresolved?
Specifically carmine/set
?
I also added a function with carmine/get which it claimed to be unresolved but I have been using in the REPL quite happily
That should run when taoensso.carmine
is required tho', right?
Oh, gotcha... FWIW, I setup a test project with Carmine and your code in VS Code/Calva/LSP and carmine/set
is not flagged as unresolved...
Hmm, interestingly, carmine/i-do-not-exist
is also not flagged... Weird š
I think it might be a macro issue: https://github.com/clojure-lsp/clojure-lsp/issues/356
but I think at base level it is just the static analysis kondo does cannot tell that defcommands is introducing definitions into the carmine namespace, so as far as kondo is concerned those names don't exist
On a separate note: it's not a good idea to have side-effecting stuff in def
or defonce
:
(defonce conn-pool (carmine/connection-pool {}))
That will run whenever the namespace is first loaded in a process which will include when you try to compile it to build an uberjar.(and since {}
is provided, it will attempt to connect to the default localhost Redis instance when it is loaded -- I don't have Redis running locally on 6379 so your code will not load/compile for me)
The same applies to car-opts
since it depends on conn-pool
having been evaluated.
You also do not want ~car-opts
inside your macro. car-opts
is a resolvable symbol at that point, not something you can unquote.
The following changes would address both of these issues:
(defonce conn-pool (delay (carmine/connection-pool {})))
(def conn-spec {:uri ""})
(def car-opts (delay {:pool @conn-pool :spec conn-spec}))
(defmacro wcar* [& body] `(carmine/wcar @car-opts ~@body))
Thanks - I need to extract some of that to .env files eventually for sure. I just started this project today as a first Clojure project
With those two delay
and @
(deref) added, it will load/compile for me.
You probably need conn-spec
first and (carmine/connection-pool conn-spec)
for that to work correctly?
The macro, I copied from the Carmine quickstart page. It actually doesn't work, but that's not why the symbols don't resolve. I don't actually know how to write clojure macros yet š
@U0NCTKEV8 is that specific to this package then, or is there a general Kondo misconfiguration?
We used to use Carmine at work but we switched to just using the Jedis library via interop from Clojure.
clj-kondo
cannot know about anything defined by code-at-runtime like that -- unless the library also provides all the definitions to clj-kondo
via exports.
Carmine has no clj-kondo
exports configuration.
Now that I have a working REPL (after those code changes), I do get the carmine/set
warning BTW:
(so you can see Calva is able to retrieve the docstring just fine via the REPL but clj-kondo
cannot do static analysis because taoensso.carmine
does not contain a (statically detectable) set
function).
Got it, thanks. Off topic - I noticed that you use VSCode over Emacs and that you're very experienced in Clojure. I learned Emacs over the past couple of days partially because I thought it's the "OG" way of working with Clojure and wanted to dive into the deep end. Is that not the case, at the higher levels of Clojure experience?
I started with Emacs back in the 17.x days and used it through 19.x (for C mostly) then switched out to other IDEs while I did C++ and Java etc. When I started with Clojure (2010), I came back to Emacs and tried a lot of different configurations over the years (including Prelude) but ultimately just found Emacs a) a bit too clunky after using a bunch of "modern" editors and b) required too much "care & feeding" in terms of trying to maintain a stable, productive setup... so I switched initially to Atom and ProtoREPL, then to Atom and Chlorine, then to VS Code and Clover, and finally to VS Code and Calva (and Joyride and LSP/clj-kondo). VS Code is modern, well-supported, has a lot of useful extensions that I've come to rely on. Calva is an awesome Clojure integration. And Joyride means I can script VS Code with ClojureScript just like I used to script Emacs with elisp (only nicer, because it's cljs!).
(17.x-19.x was mid-'80s to mid-'90s)
Thanks! I like the overall Emacs experience so far but it does feel like a lot of things are not working out of the box/need a lot of IDE tinkering to work. I may stick around or may switch to VSCode.
so you didn't test Emacs with LSP yet @U04V70XH6 š
I think VsCode nowadays (after clojure-lsp integration in Calva especifically) is a good "work nice out of the box", but when you need to do lots of customizations, Emacs is better IMO
Somehow Emacs just overwrote a file I was working on with a stack trace, so I am not too happy with it right now
@UKFSJSM38 I'm curious what sort of customizations you feel can be done with Emacs but not VS Code? (i.e., am I missing something cool/useful?)
ā¢ Sometimes I feel some vscode plugins are a little bit opinated, calva for example took some time to have options to prioritize LSP features over repl ā¢ I think vscode shortcuts sucks.. doom-emacs keybindings are so good IMO, that I hardly need to add custom keybindings ā¢ The programatic way of configuring things via emacs like ifs makes me have more extensible configs ā¢ I can work entirely on emacs without a mouse, I'm not sure I have that on vscode
But overall, vscode is the only editor I'd recommend if there was no emacs, it's pretty close in most things
@UKFSJSM38 do you use shortcuts for most things or M-x
I can use VS Code entirely without a mouse -- but I've added a number of extra key bindings to make that possible (and I have a lot of custom REPL snippets š and several Joyride scripts that I use heavily).
I can't even discover how that carmine/set
var is created by reading the source code, is that a good thing? ;)
yeah, I found it by loading the code in the repl and looking at the metadata on the var which lead me to the defcommands line
One solution to suppress warnings about this namespace could be:
:linters {:unresolved-var {:exclude [taoensso.carmine]}}
here's the docs for it: https://github.com/clj-kondo/clj-kondo/blob/master/doc/linters.md#unresolved-var