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?
https://github.com/nrepl/nrepl/pull/162 has some discussion
@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.
i thought it was a general purpose code loading mechanism. but i haven't followed too closely
Although that issue also talks about handing back entire jars.
and now i'm not sure if its jar or just source based
There’s some doc, but it doesn’t clarify much: https://nrepl.org/nrepl/0.8/building_clients.html#implementing-sideloading
> 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
Oh great, thanks - I’ll try both of those.
You can sideload anything that you can normally load via a classloader.
> I have a vague recollection that pomegranate had problems under the module system, did that ever get fixed? Is anyone doing this?
Yep, those were fixed.
(that's the bugfix https://github.com/nrepl/nrepl/pull/190)
And a follow-up, as it turned out that the fix was causing some issues with Orchard on JDK 8.
@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
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.
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.
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?
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.
> I’m guessing that for things like classes, the server will request them one by one rather than requesting a full jar.
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).
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.
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.
> 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.
Same as me then. 🙂
> But for loading dependency jars, I’m not sure how that would work.
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.
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
Ok, thanks. I might look at using sideloading to load something like pomegranate, and then using that to load deps.