clojure

jpalharini 2026-02-23T19:01:43.347759Z

@seancorfield we recently updated org.clojure/core.cache to 1.2.254 and apparently https://github.com/clojure/core.cache/commit/c15b60d09f417636b4e9239fbb421ef8ba4feb6f makes the cache store exceptions for keys, which didn't happen before. https://gist.github.com/jpalharini/d92656a06b281f0ba87c459b346f598c will store a cache entry for "throw" in 1.2.254, but not store it in 1.1.234. I'm wondering if this is actually the expected behavior considering we want to ensure value-fn/wrap-fn is called at most once, and evicting invalid entries is supposed to be done on the consumer side, or perhaps by implementing a "validating" cache.

😵‍💫 1
seancorfield 2026-02-23T19:18:06.552289Z

Interesting. That was not an intentional change in behavior -- but I will note https://clojure.atlassian.net/browse/CMEMOIZE-31 which was raised against core.memoize for a similar issue: exceptions are cached. Can you create an Ask with details and reference both CCACHE-65 and CMEMOIZE-31 and I'll have a think about solving both? (I was already investigating CMEMOIZE-31)

seancorfield 2026-02-23T19:18:39.355939Z

Ask = https://ask.clojure.org

jpalharini 2026-02-23T19:19:12.440519Z

Sure! I'll do that by tomorrow at the latest.

seancorfield 2026-02-23T19:35:40.576229Z

Ah, it doesn't (technically) cache an exception, it caches a delayed fn invocation, and the invocation throws when fetched from the cache. Which is the same bug as core.memoize already had, because it takes a similar approach. I wonder if I can switch to some sort of promise/deliver implementation that doesn't deliver exceptions...?

jpalharini 2026-02-23T19:36:15.520699Z

Yep, it caches the delay. Sorry, I should've been clearer.

Ingy döt Net 2026-02-23T19:26:57.663589Z

How many clojure.core functions/macros does clojure.core/println depend on? 1️⃣ 3 2️⃣ 12 3️⃣ 42 4️⃣ 85 5️⃣ 117 React with your answer! 👇

4️⃣ 4
3️⃣ 3
souenzzo 2026-02-25T14:02:51.704289Z

requiring-resolve: 166 is the largest

✅ 1
lassemaatta 2026-02-26T04:19:34.090829Z

would be interesting to see a DOT graph of the dependencies 🤔

Ingy döt Net 2026-02-26T05:23:18.891059Z

I could do that pretty easily, but so could you. Here's the data for you. https://github.com/gloathub/gloat/blob/main/build/clojure-core.yaml

👍 1
Ingy döt Net 2026-02-26T05:25:05.856169Z

PS I'm fascinated by your surname. 😄

😄 1
Ingy döt Net 2026-02-26T05:29:12.495809Z

böws döwn! 😂

Ingy döt Net 2026-02-26T05:31:21.261339Z

I feel like the graph for the entire core library is going to be extremely busy.

Ingy döt Net 2026-02-26T05:32:20.066699Z

Maybe just start with a dot graph for println

lassemaatta 2026-02-26T06:02:28.816969Z

And if you gaze for long into an abyss, the abyss gazes also into you.

Ingy döt Net 2026-02-26T07:23:47.268099Z

omg

souenzzo 2026-02-26T13:17:16.495829Z

What is M?

lassemaatta 2026-02-26T13:41:08.074739Z

I think those are supposed to be various macros, but `clj-yaml` seems to parse foo/M as M I don't know how to write code.

souenzzo 2026-02-26T13:42:17.470299Z

So it ended up combining several ../M into one.

lassemaatta 2026-02-26T14:02:43.925879Z

you can almost see something from this. perhaps I'll see if I can graph the dependencies of a particular function, if it looks any clearer.

Ingy döt Net 2026-02-26T15:49:50.304429Z

@souenzzo in the https://github.com/gloathub/gloat/blob/main/build/clojure-core.yaml data I added /M to the macros and /S to the special forms

Ingy döt Net 2026-02-26T15:50:59.776159Z

They could just be removed here.

Ingy döt Net 2026-02-26T15:53:08.650919Z

Ingy döt Net 2026-02-26T16:05:48.468139Z

I can make out concat on that middle one

souenzzo 2026-02-26T16:08:22.674909Z

Many macros use concat. Not sure if your algorithm consider ~@ as a concat.

Ingy döt Net 2026-02-26T16:09:52.183119Z

I got the data by scraping the Glojure AOT code, where I think macros are expanded.

Ingy döt Net 2026-02-24T17:45:34.205239Z

BTW -Xprune works now with 50% size reduction and 80% startup time reduction 🙂

2026-02-24T18:17:34.006379Z

holy crap lol

Ingy döt Net 2026-02-24T18:24:04.949349Z

YS's ys.std/say avoids clojure.core print calls but still needs to call apply and str and a few others

Ingy döt Net 2026-02-24T18:26:12.264549Z

It's so nice to have a clear lens into this stuff. I think gloat -Xdeps will be super useful even to non- #glojure people.

2026-02-23T19:33:18.051259Z

too many hah

Ingy döt Net 2026-02-23T19:34:00.034439Z

it's a fun pop trivia quiz! take a guess!

❤️ 1
Ingy döt Net 2026-02-23T19:34:54.004619Z

Afterwards I'll show you how many deps every cc form has 🙂

Ludger Solbach 2026-02-23T19:36:31.825199Z

I'm not going to count!

😄 1
2026-02-23T19:42:55.116789Z

i actually ran into this when writing a formatter for Project Fluent files last year. I couldn't find the source of the the poor performance (vs a 1-to-1 version in java) until i tracked it down to calling pr-str instead of Writer/.write.

✅ 1
Michael Griffiths 2026-02-23T19:48:41.430159Z

do you only mean first-order dependencies? technically printing bottoms out at print-method / print-dup which are multimethods (i.e. arbitrarily open to extension) so i'd say the answer is "it depends" 😄

Ingy döt Net 2026-02-23T19:49:15.641109Z

I found out the answer originally when I was compiling a Clojure to Go code to binary file and wondering why it was so huge. See https://gloathub.org/blog/2026/02/22/introducing-gloat-and-glojure/ My source code only used println and some other trivial function like inc. I removed the rest of the code, but it was still a pretty huge binary after that.

Ingy döt Net 2026-02-23T19:50:38.718429Z

> do you only mean first-order dependencies? No, I mean the recursive dependency tree. Unique functions/macros of that tree.

Ingy döt Net 2026-02-23T22:42:28.773329Z

Okay, time's up. Here's the answer. https://gist.github.com/ingydotnet/0423ea7fbcfc653393f598eb6ee66501#file-clojure-core-deps-counts-yaml-L413

Ingy döt Net 2026-02-23T22:43:25.919959Z

@nbtheduke 🥇

🎉 1
2026-02-23T22:45:28.980339Z

a winner is me!

🙌 1
Ingy döt Net 2026-02-23T22:46:34.633889Z

@nbtheduke I honestly thought everybody would copy you. 😄

2026-02-23T22:48:01.326629Z

i was worried it was higher!

Ingy döt Net 2026-02-23T22:49:47.900099Z

requiring-resolve is 162!! https://gist.github.com/ingydotnet/0423ea7fbcfc653393f598eb6ee66501#file-clojure-core-deps-counts-yaml-L461

🙈 2
Ingy döt Net 2026-02-23T22:50:45.028379Z

I'm working on a system to do some tree shaking on the AOT compilation process to go code.

Ingy döt Net 2026-02-23T22:53:10.915849Z

Pretty much every binary executable is going to have a println. All it needs is Go fmt.Println For general stuff, not 85 extra functions.

Ingy döt Net 2026-02-23T22:54:11.194009Z

Since most of my input is YAMLScript anyway, YS has say for println So I can just make that do the fast thing. Can't really mess with clojure.core/println

Ingy döt Net 2026-02-23T22:56:21.111589Z

I guess for Clojure tree shaking purposes, people could just replace println in their ns with a function that does Go interop to fmt.Println

Ingy döt Net 2026-02-23T22:58:15.317909Z

I should be able to get that done this week. gloat -Xprune foo.clj && ls -lh foo

Ingy döt Net 2026-02-23T22:58:53.088809Z

Right now all the binaries are weighing in around 65MB. I think that's stripped but I'm not 100%.