nrepl

https://github.com/nrepl/nrepl || https://nrepl.org
cfleming 2020-10-01T03:19:57.009200Z

What is the current state of being able to load libraries dynamically into an nREPL REPL? I have a vague recollection that pomegranate had problems under the module system, did that ever get fixed? Is anyone doing this?

dpsutton 2020-10-01T03:34:37.009500Z

https://github.com/nrepl/nrepl/pull/162 has some discussion

cfleming 2020-10-01T03:57:55.010400Z

@dpsutton Isn’t that different, though? My understanding was that that would go back from the server to the client for a namespace if it couldn’t be found on the server.

dpsutton 2020-10-01T04:00:19.011100Z

i thought it was a general purpose code loading mechanism. but i haven't followed too closely

cfleming 2020-10-01T04:00:27.011400Z

Although that issue also talks about handing back entire jars.

dpsutton 2020-10-01T04:00:31.011600Z

and now i'm not sure if its jar or just source based

cfleming 2020-10-01T04:03:14.011900Z

There’s some doc, but it doesn’t clarify much: https://nrepl.org/nrepl/0.8/building_clients.html#implementing-sideloading

flowthing 2020-10-01T09:41:33.013200Z

> My understanding was that that would go back from the server to the client for a namespace if it couldn’t be found on the server. I believe the sideloader is exactly for that purpose, yeah. I don't think it can handle JAR files, but someone can correct me if I'm wrong. This is the only thing I'm aware of with regard to hot-loading libs: https://nrepl.org/nrepl/0.8/usage/misc.html#hot-loading-dependencies

cfleming 2020-10-01T19:29:14.013500Z

Oh great, thanks - I’ll try both of those.

bozhidar 2020-10-01T20:32:49.013900Z

You can sideload anything that you can normally load via a classloader.

bozhidar 2020-10-01T20:33:10.014100Z

> I have a vague recollection that pomegranate had problems under the module system, did that ever get fixed? Is anyone doing this?

bozhidar 2020-10-01T20:33:13.014300Z

Yep, those were fixed.

bozhidar 2020-10-01T20:34:28.014500Z

(that's the bugfix https://github.com/nrepl/nrepl/pull/190)

bozhidar 2020-10-01T20:35:38.015300Z

And a follow-up, as it turned out that the fix was causing some issues with Orchard on JDK 8.

bozhidar 2020-10-01T20:35:40.015500Z

https://github.com/nrepl/nrepl/pull/210

cfleming 2020-10-01T20:39:30.016400Z

@bozhidar How does that work, then? I’m not sure how this should work from either a client implementation or a user UI point of view

cfleming 2020-10-01T20:40:36.017400Z

In my mind, a user would say “I’d like to use library x”, Cursive downloads the lib and its deps and then sends them to the server. I’m not sure how this works with this model.

cfleming 2020-10-01T20:43:12.019Z

What I had envisioned for the sideloading had been more the namespaces that Cursive loads for e.g. completion, i.e. I call cursive.runtime/complete or whatever, the server sees it doesn’t have that and requests it from the client.

cfleming 2020-10-01T20:46:10.021200Z

But for loading dependency jars, I’m not sure how that would work. Do I create a sideloading session for each dep the user wants to load? I’m guessing that for things like classes, the server will request them one by one rather than requesting a full jar. But that then means that I have to keep the sideloading session open for as long as the user might eval something using that dep, right?

bozhidar 2020-10-01T21:03:49.022800Z

Yeah, exactly. Basically when you try to require something that's not present nREPL will ask you to provide the missing resource. As you don't want to this to happen in the main eval session it makes sense to either have a dedicated session for sideloading or one-off sessions.

bozhidar 2020-10-01T21:03:59.023Z

> I’m guessing that for things like classes, the server will request them one by one rather than requesting a full jar.

bozhidar 2020-10-01T21:06:45.025300Z

Yep, the Clojure classloader doesn't have a notion of jars - it understands classfiles and Clojure source files, so on requiring something you'll have to supply one of those. As this was envisioned mostly to load things like development libraries (e.g. code completion) that's not a big deal as they are typically simple (often just a couple of namespaces).

bozhidar 2020-10-01T21:08:03.026300Z

I think Tutkain and iced-vim are already using the sideloader, so you can check their code for details. CIDER also has some pretty basic support, as I hadn't had much time for it lately.

bozhidar 2020-10-01T21:10:31.027900Z

As you can see from the code my idea was just to bundle some libraries with CIDER directly (e.g. Orchard and Compliment) and sideload them from there, but obviously you can go in whatever direction you want to.

bozhidar 2020-10-01T21:10:58.028100Z

> What I had envisioned for the sideloading had been more the namespaces that Cursive loads for e.g. completion, i.e. I call cursive.runtime/complete or whatever, the server sees it doesn’t have that and requests it from the client.

bozhidar 2020-10-01T21:11:01.028300Z

Same as me then. 🙂

bozhidar 2020-10-01T21:11:33.028500Z

> But for loading dependency jars, I’m not sure how that would work.

bozhidar 2020-10-01T21:12:59.030Z

Well, you can also utilize pomegranate as clj-refactor was doing it in the past. It had functionality very similar to what you're describing - you could select some library from clojars or Maven Central and load it into the running nREPL server.

bozhidar 2020-10-01T21:14:27.030800Z

They were using alembic and it got broken with Java 9, though. Afterwards this code was never updated to use pomegranate or something else https://github.com/clojure-emacs/clj-refactor.el/issues/466

cfleming 2020-10-01T22:24:58.031500Z

Ok, thanks. I might look at using sideloading to load something like pomegranate, and then using that to load deps.