clojure-dev 2026-07-02

1.13.0-alpha1 breaks Rebel Readline. The following two functions work on 1.12:

;; pulling out core vars for
(defn filter-core-var-meta [f]
  (->> (clojure.repl/dir-fn 'clojure.core)
       (map (juxt (comp meta resolve) identity))
       (filter (comp f first))
       (map second)
       (map name)))

(defn core-vars []
  (filter-core-var-meta #(and (not (:arglists %))
                              (not (:macro %))
                              (.startsWith (-> % :name name) "*"))))
But on 1.13 that produces an NPE because there's no :name element on a couple of new things:
(clojure.core.proxy$clojure.lang.APersistentMap$ff19274a clojure.core.proxy$java.io.Writer$ff19274a)
So, if I'm reading that right, I think this are newly added with no metadata? Seems to be:
(!2003)-> clj -M:1.12
Clojure 1.12.5
user=> (->> (clojure.repl/dir-fn 'clojure.core) (filter (comp nil? meta resolve)))
()
user=>

(2026-07-02.16:04:50)-(~/.config/clojure)
(!2004)-> clj -M:1.13
Clojure 1.13.0-alpha1
user=> (->> (clojure.repl/dir-fn 'clojure.core) (filter (comp nil? meta resolve)))
(clojure.core.proxy$clojure.lang.APersistentMap$ff19274a clojure.core.proxy$java.io.Writer$ff19274a)
user=>

Alex Miller (Clojure team) 2026-07-02T20:11:13.705609Z

there are a couple of new private functions in core to support the destructuring additions. not sure what else it could be other than that

Alex Miller (Clojure team) 2026-07-02T20:16:49.581189Z

I don't know what the context is, but maybe should remove private stuff?

Does dir-fn return private vars? Doesn't seem to:

user=> (->> (clojure.repl/dir-fn 'clojure.core) (filter (comp :private meta)))
()
user=> (->> (clojure.repl/dir-fn 'clojure.core) (filter (comp :private meta resolve)))
()
(or am I doing that wrong?)

> Does dir-fn return private vars? It shouldn't.

> (:doc (meta #'clojure.repl/dir-fn))
"Returns a sorted seq of symbols naming public vars in
 a namespace or namespace alias. Looks for aliases in *ns*"

user=> (->> (clojure.repl/dir-fn 'clojure.core) (filter #(not= clojure.lang.Var (type (resolve %)))))
(clojure.core.proxy$clojure.lang.APersistentMap$ff19274a clojure.core.proxy$java.io.Writer$ff19274a)

Everything else is a Var...

So... dir-fn is now returning two things that are not "public vars"?

Alex Miller (Clojure team) 2026-07-02T20:32:24.966169Z

I don't see the new fns (`destvec*` and destmap*) coming back from dir-fn. I was just guessing those were the difference as not much else has changed in core (other than req!).

i don't see anything that would cause this

Alex Miller (Clojure team) 2026-07-02T20:35:28.315929Z

that code at the top doesn't NPE for me in a normal repl, what's different in rebel-readline?

user=> (filter #(not= clojure.lang.Var (type (resolve (first %)))) (ns-publics 'clojure.core))
([clojure.core.proxy$java.io.Writer$ff19274a #'clojure.core/clojure.core.proxy$java.io.Writer$ff19274a] [clojure.core.proxy$clojure.lang.APersistentMap$ff19274a #'clojure.core/clojure.core.proxy$clojure.lang.APersistentMap$ff19274a])

๐Ÿ˜ฎ 1

Those items have no metadata. Rebel's code assumes every Var has metadata -- but these are not Vars.

Since the memory hex is the same, does that mean some ns mapping in core now has a proxy of those two types?

On 1.12.5, that filter of ns-publics returns an empty list.

Can someone at least confirm what I'm seeing different between 1.13 and 1.12 in a bare Clojure REPL?

Alex Miller (Clojure team) 2026-07-02T20:46:43.711989Z

I see that

Thanks. Glad it's not just "my machine" ๐Ÿ™‚

> that code at the top doesn't NPE for me in a normal repl, what's different in rebel-readline? I should have been clear that the NPE is when (core-vars) is called but we've moved on from that now...

Must admit, I don't see any changes since 1.12.5 that would lead to this...

Alex Miller (Clojure team) 2026-07-02T21:01:29.561279Z

bisecting

the pprint problem is also related to proxies

Looks like there are a whole lot of new reflection warnings in 1.13? This is from athos/clj-check.

Alex Miller (Clojure team) 2026-07-02T21:12:15.077179Z

might be java version dependent (new arities can make things newly reflective)

I'm on JDK 27 locally -- but I don't get these warnings with Clojure 1.12.5.

is one of the updated POM plugins 'helping' us with modules?

Alex Miller (Clojure team) 2026-07-02T21:16:30.537389Z

it is definitely the plugin update commit that shows the change so that is the path I am down

who needs bisect when you have logic?

Alex Miller (Clojure team) 2026-07-02T21:17:21.752029Z

by "bisect" I really meant, make a logical guess, I didn't actually use bisect

๐Ÿ‘ 1

I've been looking at the pprint - we obviously have pprints in the build tests and yet it fails in the REPL - classes that should be derived from each other are unrelated due to modules

Alex Miller (Clojure team) 2026-07-02T21:36:38.206899Z

I can't fully explain it yet, but I am fairly sure this is due to setting the outputTimestamp and how that plays with the newer version of the jar plugin, causing the class / clj loading (based on timestamp) to do something different wrt protocol classes

Interesting... I read Ambrose's blog post about the timestamp thing for reproducible builds...

Just FYI: things fail at work with 1.13 due to the pprint issue that was also reported.

Alex Miller (Clojure team) 2026-07-02T21:58:38.654659Z

alpha2 is building, sorry about that

No, this is all good. This is why there are alphas.

And why I jump on them and test early ๐Ÿ™‚

Looks like that solves the Rebel Readline issue...

Same error if we just add the outputTimestamp property without bumping any plugins. I can take a closer look.

Alex Miller (Clojure team) 2026-07-02T22:22:37.904949Z

I've reverted for now and rebuilt, will look at it later

๐Ÿ‘ 1

All tests pass at work with Alpha 2. I'll push it through CI and up onto QA for a run over the next few days, and we'll start pushing it to production early next week for heavier testing.

This message was deleted.

pprint.pprint/pprint

๐Ÿคฆ will remove the noise lol

but i can reproduce

โฏ clj -Sdeps '{:deps {org.clojure/clojure {:mvn/version "1.13.0-alpha1"}}}'
Clojure 1.13.0-alpha1
user=> (require 'clojure.pprint)
nil
user=> (clojure.pprint/pprint :foo)
Execution error (ClassCastException) at clojure.pprint.proxy$java.io.Writer$IDeref$PrettyFlush$4923d848/flush (REPL:-1).
class clojure.pprint.proxy$java.io.Writer$IDeref$PrettyFlush$4923d848 cannot be cast to class clojure.pprint.PrettyFlush (clojure.pprint.proxy$java.io.Writer$IDeref$PrettyFlush$4923d848 is in unnamed module of loader 'app'; clojure.pprint.PrettyFlush is in unnamed module of loader clojure.lang.DynamicClassLoader @36a58466)
:foo

Ohh, so I was seeing something real

โฏ clj
Clojure 1.12.1
user=> (require 'clojure.pprint)
nil
user=> (clojure.pprint/pprint :foo)
:foo
nil

yup. i thought you were seeing unknown var from your typo. but thereโ€™s something there

Yeah, I was trying to isolate the issue down with a clean REPL and then typo'd ๐Ÿ˜‚

โฏ clj -Sdeps '{:deps {org.clojure/clojure {:mvn/version "1.13.0-alpha1"}}}'
Clojure 1.13.0-alpha1
user=> (clojure.pprint/pprint :foo)
Execution error (ClassCastException) at clojure.pprint.proxy$java.io.Writer$IDeref$PrettyFlush$4923d848/flush (REPL:-1).
class clojure.pprint.proxy$java.io.Writer$IDeref$PrettyFlush$4923d848 cannot be cast to class clojure.pprint.PrettyFlush (clojure.pprint.proxy$java.io.Writer$IDeref$PrettyFlush$4923d848 is in unnamed module of loader 'app'; clojure.pprint.PrettyFlush is in unnamed module of loader clojure.lang.DynamicClassLoader @36a58466)
:foo
you donโ€™t even need to require it since the repl does for the repl-requires

Yeah here it is without the typo, gonna send this to the main channel for context:

% clj -Sdeps '{:deps {org.clojure/clojure {:mvn/version "1.13.0-alpha1"}}}'
Clojure 1.13.0-alpha1
user=> (require 'clojure.pprint)
nil
user=> (clojure.pprint/pprint :foo)
Execution error (ClassCastException) at clojure.pprint.proxy$java.io.Writer$IDeref$PrettyFlush$4923d848/flush (REPL:-1).
class clojure.pprint.proxy$java.io.Writer$IDeref$PrettyFlush$4923d848 cannot be cast to class clojure.pprint.PrettyFlush (clojure.pprint.proxy$java.io.Writer$IDeref$PrettyFlush$4923d848 is in unnamed module of loader 'app'; clojure.pprint.PrettyFlush is in unnamed module of loader clojure.lang.DynamicClassLoader @56299b0e)
:foo

This may be related to the weirdness I saw with my Rebel Readline thread above according to Rich... but it's looking like something in the updated Maven plugins for the new build is the root cause. Alex is working on it.

โฏ clj -Sdeps '{:deps {org.clojure/clojure {:mvn/version "1.13.0-alpha2"}}}'
Clojure 1.13.0-alpha2
user=> (clojure.pprint/pprint :foo)
:foo
nil

1.13.0-alpha2 no longer prints warnings

Yes, they fixed the issue ๐Ÿ™‚

See the other thread...

(confirming that this particular issue is indeed resolved. there seem to be a more generic thing around proxies)

It was just one issue: the reproducible build timestamp thing that Ambrose blogged about recentlyโ€”doesn't work ๐Ÿ˜ž

Broke all sorts of things...