babashka

seancorfield 2026-05-18T15:48:45.940099Z

I'm struggling to remember (or find in the docs) how to run a main fn with arguments in-process in a bb task. I know I can have :task lazytest.main/-main to run main in process with no args...

2026-05-18T15:49:05.909679Z

in-process?

seancorfield 2026-05-18T15:49:27.109439Z

i.e., with babashka rather than a shell process

borkdude 2026-05-18T15:49:41.229509Z

(binding [*command-line-args* ...] (lazytest.main/-main))
or (apply ...) if the main function just uses the fn args instead of the command line var

seancorfield 2026-05-18T15:50:06.097169Z

I was overthinking it 🙂

borkdude 2026-05-18T15:50:07.022209Z

or just (-main ...)

seancorfield 2026-05-18T15:52:00.932399Z

Am I holding it wrong?

35: (def test:bb (binding [
36:   babashka.tasks/*task* '{:name test:bb, :extra-paths ["dev" "test"], :extra-deps {io.github.noahtheduke/lazytest {:mvn/version "2.0.0"}}, :task (do (require 'lazytest.main) (lazytest.main/-main "-n" "org.corfield.rephrase-test"))}]
37:   nil
38: (do (require 'lazytest.main) (lazytest.main/-main "-n" "org.corfield.rephrase-test")))) test:bb
                                 ^--- Unable to resolve symbol: lazytest.main/-main

seancorfield 2026-05-18T15:52:23.166159Z

test:bb {:extra-paths ["dev" "test"]
           :extra-deps  {io.github.noahtheduke/lazytest {:mvn/version "2.0.0"}}
           :task (do
                   (require 'lazytest.main)
                   (lazytest.main/-main "-n" "org.corfield.rephrase-test"))}

borkdude 2026-05-18T15:53:00.333309Z

this has to do with the whats-it-called problem that technomancy has on his blog. use :requires ([...]) to add the require in there

seancorfield 2026-05-18T15:53:02.184819Z

If I have :task lazytest.main/-main it "runs" (but fails because it loads a ns that I can't test in bb)

2026-05-18T15:53:29.772829Z

gilardi scenario?

borkdude 2026-05-18T15:53:32.881669Z

yes

seancorfield 2026-05-18T15:54:32.080079Z

Okay, now I guess I have a Q for @nbtheduke -- that command-line is loading other test nses. I only want that one.

borkdude 2026-05-18T15:54:32.431279Z

:requires ([lazytest.main :as lazytest])

seancorfield 2026-05-18T15:55:22.832309Z

test:bb {:extra-paths ["dev" "test"]
           :extra-deps  {io.github.noahtheduke/lazytest {:mvn/version "2.0.0"}}
           :requires [[lazytest.main]]
           :task (lazytest.main/-main "-n" "org.corfield.rephrase-test")}

seancorfield 2026-05-18T15:56:54.281659Z

Ah, that command doesn't work with the JVM version either... it also loads a test ns it shouldn't.

borkdude 2026-05-18T15:57:15.413439Z

maybe your test-ns loads that ns accidentally?

seancorfield 2026-05-18T15:57:29.032059Z

No, it's lazytest loading it.

👍 1
2026-05-18T15:57:35.345849Z

moving the thread to #lazytest

seancorfield 2026-05-18T15:58:22.701919Z

Ah, it loads all nses, but only runs the specified one. Ugh! Okay, I'll need reader conditionals here I suspect...

borkdude 2026-05-18T15:58:44.042329Z

or use the cognitect test runner for bb, which doesn't load all nses I believe

borkdude 2026-05-18T15:58:47.362459Z

or fix lazytest

borkdude 2026-05-18T15:59:15.088489Z

why is it even called lazytest if it eagerly loads stuff 🥁

😄 1
seancorfield 2026-05-18T16:00:45.690029Z

The tests use LazyTest terminology, not clojure.test 🙂

borkdude 2026-05-18T16:01:27.119429Z

I guess you could mock the conflicting ns with a .bb file

borkdude 2026-05-18T16:01:42.309179Z

instead of using reader conditionals

seancorfield 2026-05-18T16:09:41.654069Z

Back to a bb question with this now:

3: (ns org.corfield.rephrase
4:   (:require [clojure.main :refer [ex-triage]]
     ^--- ex-triage does not exist
Babashka's clojure.main doesn't have that fn?

borkdude 2026-05-18T16:13:33.502869Z

currently not apparently

borkdude 2026-05-18T16:13:42.516329Z

issue welcome and I'll add it

seancorfield 2026-05-18T16:25:07.601519Z

It requires copying in several helper functions so it's quite a bit of code...

seancorfield 2026-05-18T16:25:57.593579Z

I created the issue. I'll hold off my experiments now until that's done -- whenever you get to it, absolutely no rush.

borkdude 2026-05-18T17:26:19.458129Z

you can work around it by interning a fake var in that namespace

seancorfield 2026-05-18T18:20:26.302689Z

Well, the tests won't run with that so I wouldn't get much further, unfortunately. And ex-triage pulls in a bunch of helper functions that may or may not run on bb.

seancorfield 2026-05-18T01:47:22.763809Z

Q about Babashka and nREPL: does bb support any nREPL middleware? I'm thinking the answer is "no" or "yes, but very limited". It doesn't seem to have the wrap-caught middleware in babashka.nrepl and nrepl/nrepl itself (which does have that middleware) doesn't load on bb (due to use of definline). Context: I was wondering if I could get my rephrase library running on bb... I suspect I can get the exception rephrasing ns running but not the nrepl (middleware) ns?

borkdude 2026-05-18T07:59:45.149169Z

babashka nrepl does not yet support custom middleware. it's on my TODO list and hope to get to it towards the end of the year

seancorfield 2026-05-18T12:07:49.234219Z

Thanks @borkdude I'll revisit testing rephrase with bb after that then. Although I may still add testing the non-middleware part now...

borkdude 2026-05-18T12:09:25.768759Z

Something in me hopes that I can make a big jump in bb compatibility by just replacing SCI etc with https://github.com/borkdude/cream : that would make big swaths of existing clojure compatible without changing anything. But currently crema isn't as fast as SCI yet...

neumann 2026-05-18T17:42:23.207529Z

Cream is pretty neat, and it does seem like the future. What would that mean for SCI, Scittle, Joyride, etc?

borkdude 2026-05-18T17:52:21.621949Z

• for SCI on bb: replacement hopefully, eventually • for SCI as a sandbox: nothing • for scittle, joyride, etc.: nothing

👍 1
borkdude 2026-05-18T18:23:09.376729Z

sandboxing: perhaps crema will also offer some sandboxing, so that would then also replace SCI on JVM, but for JS nothing changes

Bob B 2026-05-18T02:09:13.018369Z

I could be (and probably am) wrong, but it seems like there's at least some support for middleware, because a really ad-hoc mess:

user=> (defn hi [handler] (println "here's some stuff") handler)
#'user/hi
user=> (babashka.nrepl.server/start-server! {:xform hi})
will print to the bb console. My guess would be that maybe the middleware has the same/similar limitations to general clojure code being run in babashka

seancorfield 2026-05-18T02:24:00.692109Z

Yeah, babashka.nrepl has some middleware (in the babashka.nrepl.middleware ns) but it doesn't have wrap-caught which is what rephrase depends on. So, I guess the real question here would be: could a version of wrap-caught be added to babashka.nrepl.middleware so that rephrase could work with bb's nREPL server? Although it would also require set-descriptor! and the topo-sorting that is based on middleware dependencies... It would be non-trivial, I suspect.

seancorfield 2026-05-18T02:29:28.812299Z

Ah, it does have the topo-sort but no set-descriptor! so metadata would have to be added "manually"... Hmm, I suspect this stuff is too dynamic to work with bb? https://github.com/nrepl/nrepl/blob/master/src/clojure/nrepl/middleware/caught.clj

seancorfield 2026-05-18T02:34:31.766459Z

I'll dig into this some more over the next few days. It looks like I could write it as simpler middleware without wrap-caught, and either use reader conditionals or a separate ns for Babashka. I'll have to give it a bit more thought.

seancorfield 2026-05-18T02:45:15.229779Z

Hmm, this is where rephrase would need to hook in and replace some of the error reporting... https://github.com/babashka/babashka.nrepl/blob/master/src/babashka/nrepl/impl/utils.clj#L22 ...that's essentially a hard-coded version that doesn't have a hook to rephrase the exception, so I'm not sure this can work.

Bob B 2026-05-18T02:57:16.188659Z

I'm very much just poking and guessing, but tracing it back, send-exception is called by send-reduce which is used as an arg to the xform from the opts to nrepl-server, so maybe there's a way to wedge something in there. I doubt this'd be a desirable/robust approach, but send-exception gets called if the response has an :ex key, so maybe it'd be possible to grab the exc earlier and replace it in the response? (I haven't considered any larger context/ramifications of that, just sort of thinking outloud)