babashka

Shantanu 2026-03-22T11:10:55.270419Z

Hi, I'm currently working on adding a simple unified (is (thrown? ...)) API for the Clojure test suite. While doing so I moved some local variables outside the syntax quote (https://github.com/jank-lang/clojure-test-suite/pull/854/commits/e5c43c0c911abcc5cce71d480729d8bb91a6efce). This works with Babashka but https://github.com/jank-lang/clojure-test-suite/actions/runs/23401604064/job/68073676949?pr=854. I was wondering could it be a bug in Babashka? Or could it be because of difference in how Babashka treats locals (or could just be me doing something wrong, but I thought it was worth bringing it up here once). Unfortunately I haven't been able to reproduce a smaller case. I'll post the macroexpansion results for Clojure JVM and Babashka in this thread, maybe it will help debugging what is going on here.

Shantanu 2026-03-22T11:11:40.594459Z

The form:

(macroexpand '(t/is (p/thrown? (abs nil))))
Babashka:
(try
 (try
  (abs nil)
  (#object[babashka.impl.clojure.test$do_report 0x2528628a "babashka.impl.clojure.test$do_report@2528628a"]
   {:type :fail,
    :message nil,
    :expected '(p/thrown? (abs nil)),
    :actual nil})
  (catch
   Throwable
   e__343__auto__
   (#object[babashka.impl.clojure.test$do_report 0x2528628a "babashka.impl.clojure.test$do_report@2528628a"]
    (#object[sci.impl.fns$fun$arity_1__1149 0x1a30bc17 "sci.impl.fns$fun$arity_1__1149@1a30bc17"]
     e__343__auto__))
   e__343__auto__))
 (catch
  java.lang.Throwable
  t__33438__auto__
  (clojure.test/do-report
   {:file clojure.core/*file*,
    :type :error,
    :line 1,
    :expected '(p/thrown? (abs nil)),
    :actual t__33438__auto__,
    :message nil})))
Clojure JVM:
(try
  (try
    (abs nil)
    (#object[clojure.test$do_report 0x7551da2a "clojure.test$do_report@7551da2a"]
     {:type :fail
      :message nil
      :expected (quote (p/thrown? (abs nil)))
      :actual nil})
    (catch Throwable e__143__auto__
      (#object[clojure.test$do_report 0x7551da2a "clojure.test$do_report@7551da2a"]
       (#object[user$eval144$fn__145$success_opts__146 0x6124287a "user$eval144$fn__145$success_opts__146@6124287a"]
        e__143__auto__))
      e__143__auto__))
  (catch java.lang.Throwable t__9863__auto__
    (clojure.test/do-report
     {:type :error
      :expected (quote (p/thrown? (abs nil)))
      :actual t__9863__auto__
      :message nil})))
Fair warning, I've used AI to format the Clojure JVM results. But from the looks of it, it seems ok.

Shantanu 2026-03-22T11:20:51.809219Z

P.S. Moving the success-opts to a local inside the syntax quote works with both Babashka & Clojure JVM. https://github.com/jank-lang/clojure-test-suite/pull/854/changes/492f97c44d65b99f8daa5cbc61152ff79a9275f5.

borkdude 2026-03-22T11:24:56.409989Z

could be related to compilation vs interpretation and non-s-exprs (like functions) in the expansion? if you can make a smaller repro (maybe with AI) would be worth looking into it.

Shantanu 2026-03-22T11:25:12.918719Z

Will try 👍.

Shantanu 2026-03-22T13:30:12.558029Z

Unfortunately I wasn't able to repro this, even with AI. Plus the new multimethod definition also breaks Basilisp. Hence I've decided to keep the let bindings inside the syntax quote, since moving them out feels like more trouble than they are worth 😅. I might try to repro it later, or maybe better would be to take a look at Clojure's analyzer to understand why it's using a NewExpr here. But I'll do that later.

👍 1