Fork me on GitHub
#beginners
<
2023-04-02
>
Julia Johannesen00:04:37

I have a record in a file that I'm trying to refer to in another file:

;; src/pkg/foo.clj

(ns pkg.foo)

(defrecord Foo [bar])
;; src/pkg/bar.clj

(ns pkg.bar
  ;; I want to refer to pkg.foo/Foo here
  )
I've tried (:require pkg.foo :refer [Foo]), but that errors? (:require pkg.foo :as foo) and referring to Foo as foo/Foo works, but I'd rather avoid that if possible...

Bob B00:04:54

I think that, since defrecord creates a class, it's necessary to import it rather than requiring it

Alex Miller (Clojure team)00:04:58

It depends how you want to refer to it - if you need the type, then yes you should import pkg.foo.Foo as a class

Alex Miller (Clojure team)00:04:41

If you want to use the constructors or functions, then you just require and use as with any other function

Julia Johannesen00:04:06

I wanted to use them in type hints

Alex Miller (Clojure team)00:04:40

Then yes, import the class

Hendrik08:04:04

Is there a way to make “go to definition” work with symbols to external libraries in calva / VSCode? Similiar to what is possible with Cursive? Eg I added ring to my deps.edn. Now I use ring/wrap-defaults in my code. I want to jump to the source of ring/wrap-defaults with “go to definition”. However, I get an error “definition not found”.

pez08:04:17

It should totally work. Might be something with the project config that is lacking.

Hendrik09:04:04

I’m using the polylith setup. Maybe this as an influence? If not: Any idea, where I can start looking for some misconfiguration?

pez09:04:07

Polylith setup should work. Maybe I don’t fully understand what is working and what is not working for you. Can you navigate to any library symbol?

Hendrik07:04:00

short update. Now it works. Some plugin ran with 100 % cpu usage and created an enormous amount of lack. Disabling some plugins and restarting solved the problem. Thanks for your help. I really appreciate it 🙂

Hendrik07:04:25

Noticed some more detail:

;in a source file of my project
(ns :require [some.3rd.partylib] ;go to definition works
             [someother.3rd.partylib]) ;go to definition works
;in some.3rd.partylib
(ns :require [someother.3rd.partylib]) ;go to definition does not work. symbol not found
So basically symbol resolution does work from within my own source files, but not within external source files. Is this expected behaviour?

pez08:04:14

Thanks for the update! Could you share what extension was causing the cpu congestion and what extensions you found problematic otherwise. @U09K620SG ran into similar problems and maybe we ca find a pattern, or at least start to collect information to help with getting a workable VS Code setup.

👀 2
pez09:04:59

As for your 3rd party lookup observation. In some situations it is to be expected, in some not. Without knowing your situation I don’t know if you have identified a bug or an expected limitation. I can speculate, though, so let’s! We know this about Calva and the tooling it relies on: • It uses both clojure-lsp and nrepl for lookup. • By default it consults nrepl first, then clojure-lsp (this is configurable) • clojure-lsp will exhibit the behaviour you describe (afaik) • nrepl needs to have evaluated a namespace in order to lookup its dependencies (or some other namespace with the same dependency) • Once nrepl has evaluated a namespace bringing in some.3rd.partylib it will be able to lookup some.3rd.partylib’s dependencies too. So, I’d say that: • if you are not connected to the REPL, then the behaviour is expected. • if you are connected to the REPL, but haven’t evaluated a namespace which “brings in” some.3rd.partylib, then it is also expected (and navigating to some.3rd.partylib will work because clojure-lsp. • if you are connected to the REPL and have evaluated a namespace bringing in some.3rd.partylib, then the behaviour is not expected. I hope this makes sense. I think it is independent on your configuration of which lookup service to consult first. At least if things are working as they should.

Hendrik07:04:52

Thanks for your response. Regarding the plugin. Unfortunately, I can’t tell, I had a ton of plugins (most of them for python and .net). And I removed them in one go without much in between testing. As for the 3rd party lookup: I am connected to the repl. I can reach some.3rd.partylib if I am requiring from my own source. I cannot go to any definition from within some.3rd.partylib file*.* One example: some.3rd.partylib requires clojure.pprint. I can jump to pprint, if I require it in my own ns and I am in that file. If I am in file some.3rd.partylib, then I cannot jump to the definition of pprint. I evaled some.3rd.partylib. It does not work. No jump possible. I evaled clojure.pprint (by requiring it from my own ns and jumping to the definition). It does not work, neither.

pez07:04:35

Interesting. What’s your setting for definition lookup priority? (Searching for priority in settings should find it for you)

pez08:04:12

Thanks, As I said, it shouldn’t matter, but just to know where we are. Can you enable the nREPL message log? It’s a command in Calva, i don’t quite remember the name, but you should find it in the command palette under Calva Diagnostics. It’s a log of messages between Calva and the nREPL server. We should be able to compare the messages for the lookups that succeed with those who fail and maybe that can tell us something.

Hendrik09:04:01

I enabled and checked the message log. I see no messages. Neither for succeding nor for failing lookups. Does this mean, that clojure-lsp is used and not the repl?

pez09:04:04

That would be consistent with the observed lookup behaviour… Do you see any messages if you evaluate something?

Hendrik09:04:01

yes I get messages, if I evaluate forms.

pez09:04:02

How do you start the REPL?

Hendrik10:04:48

Starting a nrepl from the terminal and then connect to the existing repl via Calva

pez10:04:29

Cool. And what’s the command line you use to start the REPL?

Hendrik10:04:09

I am using the deps.edn from Sean Corefield. I start the repl with: clj -A:add-libs:portal:nrepl:dev/repl:dev

pez10:04:27

Can you test if lookups work if you let Calva start the REPL? There’s a command for that in Calva, searching for Jack-in in the command palette should find it for you.

pez10:04:09

Don’t select the nrepl alias when jacking in.

Hendrik10:04:39

It works with jack-in 🙂

Hendrik10:04:49

Like you described. Without eval -> symbol not found. after eval of the http://3rd.party file -> jump to the definition works

pez11:04:23

Can you post the nrepl alias from the project deps.edn here? I get curious why it fails to satisfy Calva’s requirements.

Hendrik12:04:49

{:extra-deps {nrepl/nrepl {:mvn/version "RELEASE"}}
 :main-opts ["-m" "nrepl.cmdline"]}

pez13:04:09

Thanks. So it lacks cider-nrepl. @U04V70XH6 I guess it tells us one of the things that requires cider-nrepl to work. Strange as it sounds to me. @U023LKF2PQV When you connect Calva the way you do without jack-in, do you get a warning about that Calva’s requirements are not met? It would look like so:

Hendrik13:04:46

I get this warning. I did not notice this before or did not pay attention to it because the rest of Calva worked fine.

pez13:04:32

You are not the first who do not connect the problems with the warning. We need to figure out how to make this clearer.

pez13:04:30

Anyway, if you prefer to start the repl yourself, @U023LKF2PQV, Calva has a command for copying out the command line it uses to start the REPL. something Copy Jack-in something in the command palette. But if you are fine with letting Calva start the REPL, I recommend that.

Hendrik13:04:44

I’ll use jack-in and let Calva start the REPL. Thank you so much for your help.

🙏 2
seancorfield17:04:38

(given how you're starting your REPL, I assume you're using some variant of my deps.edn file? 🙂 )

Hendrik06:04:48

yes you are right. I’m using your deps.edn. I will try :cider-nrepl 🙂

Azzurite08:04:50

how do I easily build a vector without repeating myself? I don't want to have to write ["a" "a" "a" "b" "b" "c"] but do something like [(repeat 3 "a") (repeat 2 "b") "c"]but how do I flatten the seqs?

lispyclouds09:04:09

`[~@(repeat 3 "a") ~@(repeat 2 "b") "c"]
could be one way?

lispyclouds09:04:32

or simply (flatten [(repeat 3 "a") (repeat 2 "b") "c"]) if its a specific structure

lispyclouds09:04:59

flatten gives back a seq, if that matters

Azzurite09:04:01

oh yeah I tried the last one but "a" can actually be a seq itself in the vec I'm building, which gets rid of that

Azzurite09:04:20

I'd just want to flatten one level

lispyclouds09:04:02

the first one should work then, its a bit low level but gives a lot of control

Azzurite09:04:33

yep, thanks

Godwin Ko09:04:53

or (concat (repeat 3 "a") (repeat 2 "b") ["c"])

Azzurite09:04:24

@ULS5BHEUR thanks, that's what I'll actually go for 🙂

Godwin Ko09:04:48

or even (mapcat #(apply repeat %) [[3 "a"] [2 "b"] [1 "c"]]) 😅

Ed20:04:23

or (into [] cat [(repeat 3 "a") (repeat 2 "b") ["c"]])which will make sure you have a vector at the end

Azzurite09:04:46

I forgot, how do I pass a seq of something to a function like merge-with? i.e. (let [my-maps [{"a" 1} {"a" 2}]] (merge-with + my-maps)) (doesn't work obviously since merge-with wants seperate arguments, not a seq)

Azzurite09:04:21

right, (apply merge-with + my-maps)........