new small lib: https://github.com/borkdude/text-diff
Line-level text diffing for Clojure, ClojureScript and babashka
Produces the same unified diff format as git diff and diff -u.
Cool, I've been using in #eca and clojure-lsp the java https://github.com/java-diff-utils/java-diff-utils, maybe that can replace it
@ericdallo sure, let me know if you need anything. I just implemented what I needed to get cljfmt's diff working in bb
@borkdude so this means we will see cljfmt running in bb natively soon? 👀
@ovidiu.stoica1094 Yes, already possible, but just the "check" functionality didn't work due to the diff lib. https://github.com/weavejester/cljfmt/pull/404
Babashka https://github.com/babashka/fs: file system utility library for Clojure
Thanks @lee for his meticulous work!
0.5.32 (2026-03-16)
• https://github.com/babashka/fs/issues/215: document effect of umask on created files and directories (https://github.com/lread)
• https://github.com/babashka/fs/issues/182: enable soft & hard link tests on Windows (https://github.com/lread)
• https://github.com/babashka/fs/issues/202: gzip & gunzip now honor dest dir when specified & docstrings for default dest dir corrected (https://github.com/lread)
• https://github.com/babashka/fs/issues/231: get/set attribute functions were never following links. They now respect the :nofollow-links option (see note on JDK bugs in https://github.com/babashka/fs/blob/master/README.md#nofollow-links). Fixes: get-attribute, creation-time, last-modified-time, read-attributes*, read-attributes, set-attribute, set-creation-time, and set-last-modified-time (https://github.com/lread)
• https://github.com/babashka/fs/issues/233: test & document: canonicalize will never follow links on Windows with JDK < 24 (see https://github.com/babashka/fs/blob/master/README.md#nofollow-links) (https://github.com/lread)
• https://github.com/babashka/fs/issues/237: match Clojure version in pom to min supported version stated in README (v1.10.3) (https://github.com/lread)
https://github.com/babashka/babashka: Native, fast starting Clojure interpreter for scripting
Here are the most notable changes in the last two babashka releases (1.12.216 - 1.12.217).
Highlights
• Ongoing changes to support rebel-readline as external REPL provider (PRs pending)
• Add proxy support for Completer, Highlighter, ParsedLine, Writer, Reader
• Add clojure.repl/special-doc and clojure.repl/set-break-handler!
• Add clojure.main/repl-read
• start-repl! bypasses jline when custom :read is provided
• Performance improvements for math operations and calling functions on locals: (time (let [x 0 j 10000000] (loop [i 0 j 10000000] (if (zero? j) i (recur (inc i) (dec j)))))) is now 1.7x faster
• Add clojure.java.javadoc namespace with javadoc available in REPL https://github.com/babashka/babashka/issues/1933
• Support (source inc) and (source babashka.fs/exists?) for built-in vars https://github.com/babashka/babashka/issues/1935
• SCI: add proxy-super, proxy-call-with-super, update-proxy and proxy-mappings
• Fix deftype and defrecord inside non-top-level forms (e.g. let, testing) https://github.com/babashka/babashka/issues/1936
• SCI: deftype and defrecord no longer create vars for the type name, matching Clojure. (resolve 'Foo) returns a sci.lang.Type, #'Foo throws "Unable to resolve var".
• SCI: def now replaces var metadata instead of merging, matching Clojure semantics
• Support BABASHKA_REPL_HISTORY env var for configurable REPL history location https://github.com/babashka/babashka/issues/1930
• https://github.com/babashka/babashka/issues/1955: support -version as an alias for --version
More changes in 🧵
Other improvements
• https://github.com/babashka/babashka/issues/1954: add clojure.lang.EdnReader$ReaderException
• https://github.com/babashka/babashka/issues/1951: fix --prepare flag skipping next token
• Document -D in bb help https://github.com/babashka/babashka/issues/1903
• SCI: fix .sym on user-defined vars returning qualified symbol instead of unqualified
• SCI: add .ns and .sym field access on vars for compliment compatibility
• SCI: ns-aliases now returns identical namespace objects as find-ns
• SCI: alias now accepts namespace objects in addition to symbols
• SCI: copy-var and copy-var* now preserve :private metadata
• SCI: private vars are no longer included in ns-refers
• SCI: deftype and defrecord now macroexpand to deftype*, matching JVM Clojure, enabling code walkers like riddley
• SCI: case now macroexpands to JVM-compatible case* format, enabling tools like riddley and cloverage
• SCI: fix .getName on custom types to return fully qualified name, matching Class.getName()
• SCI: fix incorrect type hint causing method resolution failure when hint doesn't match runtime class
• SCI: fix NPE in resolve when called at runtime (e.g. inside macro body during code walking)
• SCI: fix .method on class objects routing to static instead of instance method path
• SCI: macroexpand-1 now expands (ClassName. args) to (new ClassName args) and (.method ClassName) wraps class targets in identity, matching JVM Clojure
• SCI: store current analysis context during macro invocation, enabling tools like riddley
• Add clerk and cloverage to lib tests
• Add ref-max-history, ref-min-history, ref-history-count
• Hide redundant (keyword) description in REPL completions
https://github.com/babashka/babashka/issues/1939: Disable JLine backslash escaping/shell history commands
• Add various Java classes: java.lang.reflect.Constructor, java.lang.reflect.Executable, java.util.stream.Collectors, java.lang.StackOverflowError, clojure.lang.IType, java.util.Comparator (reify)
• Bump rewrite-clj to 1.2.54, tools.cli to 1.4.256, transit-clj to 1.1.357, fs to 0.5.32
Thank you for supporting org.clojure/tools.deps.edn in 1.12.217! gratitude
I thought we stick to unix cli convention? This "-version" could cause confusion that may interpreted as seven single-character flags v e r s i o n
I know, it's super ugly but compatibility with clojure is one thing bb aims for
A nod to Java. 😃
I don't think we need to bend the rules just because "clj" or "java" has it. I'm sure (java/clj)'s cli design has its own legacy and history.
https://github.com/babashka/babashka/issues/1955#issuecomment-4049365324
@snow40479 clojure -version java -version cljr -version -- it's a pragmatic choice to be compatible with other tools in our (Clojure) ecosystem.
Well, given that we have things like '-Sforce' '-Sdeps', I guess the rule is already bent in bb, so never mind.
Java has supported --version for jonk's tho.
> java --version
openjdk 25.0.2 2026-01-20 LTS
OpenJDK Runtime Environment Temurin-25.0.2+10 (build 25.0.2+10-LTS)
OpenJDK 64-Bit Server VM Temurin-25.0.2+10 (build 25.0.2+10-LTS, mixed mode, sharing)Yes, java -version and java --version both work.
clojure -version and clojure --version both work too.
Same with cljr.
The clj style of "-Ttools -M:xx -T:tool" is absolutely horrible, but I guess the virus has already affected bb, it's too late now.🥹
Try bb -XX:PrintFlags= for more exceptions to the beautiful unix cmd line rules ;)
(this comes from graalvm, not bb itself)
In a perfect land, I suppose we shall have some like --substrate-vm-opts="-Xmx256M" instead 🙂
graalvm doesn't let you handle these, it's too late by the time you get to the cmd line args
I see..
@borkdude it just occurs to me maybe there IS a way to enforce beautiful unix cmd line rules, but totally not worth the effort I guess. For example, if user needs graalvm flags and input bb --substrate-vm-opts="-Xmx256M"`` , we parse it and spin up a subprocess bb with the origianl command like bb -Xmx256M xxx that user won't notice. 🤔
@snow40479 And for bb -version it would spin up a new bb --version process? 😄
no, i'm talking about 'graalvm doesn't let you handle these, it's too late by the time you get to the cmd line args'. bb -version shall just get deprecated! haha
I don't try to hide or adapt graalvm or clojure CLI stuff, I embrace it. hiding stuff isn't the clojure way
yeah, it's just my random thought anyway.
Fun trivia: java -version writes to stderr, java --version writes to stdout.
core.async 1.9.859-alpha4 is now available • https://clojure.atlassian.net/browse/ASYNC-273 (CLJ) alts!! callbacks should dispatch on caller when possible • https://clojure.atlassian.net/browse/ASYNC-274 (CLJ) Fixed flow/futurize stopped returning a future on Executor change (-alpha3 regression) • https://clojure.atlassian.net/browse/ASYNC-270 (CLJ) futurize with no :exec arg throws
if f throws fut never gets completed, unsure what the contract around exceptions futurize is meant to have, but that is still a change in behavior vs. a future from an executor service. another change is around future-cancel
can you put that on http://ask.clojure.org ?
@hiredman Regarding the contract around exceptions, we could define that to see if we could derive one. At the moment we only promise a Future but could say more if needed. Regarding, future-cancel can you elaborate?
I was thinking that completablefuture didn't have a .cancel but it does
I didn't look too much into yesterday, but that fact that futurize is exposed here https://github.com/clojure/core.async/blob/master/src/main/clojure/clojure/core/async/flow.clj#L329-L341 seems like it has preserve the exception throwing behavior on deref? otherwise any users would get a nasty surprise if their function throws and then the future never completes
and for example https://github.com/clojure/core.async/blob/master/src/main/clojure/clojure/core/async/flow/impl.clj#L259 could just hang forever if the step function threw for some reason
https://ask.clojure.org/index.php/14994/is-the-recent-change-to-flows-futurize-safe