Clojure Deref (Oct 27, 2023)

Clojure Deref (Oct 27, 2023)

27 October 2023
Alex Miller

Welcome to the Clojure Deref! This is a weekly link/news roundup for the Clojure ecosystem (feed: RSS). Thanks to Anton Fonarev for link aggregation.

From the core

Last week we released Clojure 1.12.0-alpha5 with a change in lazy-seq and delay to avoid virtual thread pinning in Java 21. Even if you are not using Java 21, this change may affect latency, allocation, or GC. If you are able to test it in the context of an application with known performance profile, we would be very interested in any feedback even if it’s just "no change".

I’ve previously mentioned adding support for a new type hint syntax for array classes (CLJ-2807). We’ve decided to expand that to a value syntax for array classes as well so that just as you can use a symbol with class name now to get the class value, you will be able to do the same with array classes. That decision led to some deeper thinking about how that new usage may potentially conflict with symbol namespace mappings (particularly for the primitive array cases) due to the common idiom of using a suffixed * to indicate a variant or internal version of a function. I’m not sure we are 100% settled yet, but I think we’re going to slightly alter the syntax to make name clashes less likely. Array class symbols will now use the syntax String-* and primitives will look like long-*. This will be the same in either type hints or in value syntax.

Method thunk work has been broken up into a series of smaller tickets (CLJ-2805, CLJ-2806, CLJ-2793) and been through a couple review cycles, continues to march toward final screening. I don’t think there are any open questions there, just a matter of review and code improvement.

I’ve been working through various final parts of the functional interface adapter work. The biggest recent change is to focus on using a set of static adapter functions (created once via a code generator) rather than emitting static synthetic adapter methods in compiled functions. In either case we’re using invokedynamic so the adapter methods can cosplay as Java functional interfaces. Moving to static adapters lets us also easily handle adapting Clojure primitive functions so that those can line up and stay primitive when adapting to functional interfaces that use primitives. There are also dimensions of work to handle eval vs compile variants, and to handle Clojure function adapters vs method thunk adapters (where the previous work crosses into this one).

There is a lot of syntax and compiler novelty in these features, which is why they are are taking so long to finish, but the extra thinking time is paying a lot of dividends and I continue to be as excited about the changes in this release as any Clojure release in a long time. We are going to deliver a lot of new capability, but in a way that I think will feel highly integrated with the Java interop you’ve used for years.

Blogs, articles, and projects

Libraries and Tools

New releases and tools this week: