Share your thoughts in the 2024 State of Clojure Survey!

Welcome! Please see the About page for a little more info on how this works.

+3 votes
in Clojure by

Hey Alex :)

Think this may be a compiler bug - necessary conditions seem to be:

  • Custom reader macro
  • Used in destructuring in defn
  • AoT compiled

e.g.

(ns foo
  (:require my.reader-macros))

(defn foo [{:keys [a], :or {a #my/reader-macro "..."}]
  ...)

In the class file, I get:

static {
    __init0();
    __init1();
    Compiler.pushNSandLoader(RT.classForName("foo__init").getClassLoader());

    try {
        load();
    } catch (Throwable var1) {
        Var.popThreadBindings();
        throw var1;
    }

    Var.popThreadBindings();
}
  • load() calls new foo.loading__9166().invoke(), which applies the :requires
  • but, in the __init1() (in my case) it tries to create the vars, including applying the arglists metadata. In applying that metadata, it has:

        RT.keyword((String)null, "or"), 
        RT.map(new Object[]{Symbol.intern((String)null, "a"), RT.readString("#my/reader-macro \"...\"")})
    

    and the RT.readString call fails with 'unbound var' because my.reader-macros hasn't been required yet.

Work-around is easy enough, and I daresay it's relatively rare given removing any of the three conditions above fixes the issue, but thought I'd raise nonetheless :)

Cheers,

James

Please log in or register to answer this question.

...