4 min read

Yesterday the team at Clojure released Clojure 1.10, a dynamic, general-purpose programming language. Clojure treats the code as data and has a Lisp macro system.

What’s new in Clojure 1.10?

Java compatibility and dependencies

  • Java 8 is the minimum requirement for Clojure 1.10.
  • Clojure 1.10 comes with ASM 6.2 and updates javadoc links.
  • Conditional logic has been removed in this release.
  • Added type hint to address reflection ambiguity in JDK 11.
  • spec.alpha dependency has been updated to 0.2.176
  • core.specs.alpha dependency has been updated to 0.2.44

Error Printing

In Clojure 1.10, errors are categorized into various phases such as:

  • :read-source: It is an error thrown while reading characters at the REPL or from a source file.
  • :macro-syntax-check: It is a syntax error found in the syntax of a macro call, either from the spec or from a macro which throws IllegalArgumentException, IllegalStateException, or ExceptionInfo.
  • :macroexpansion: All the errors thrown during macro evaluation are termed as macroexpansion errors.
  • :compile-syntax-check: It is a syntax error caught during compilation.
  • :compilation: It is a non-syntax error which is caught during compilation.
  • :execution: Any error thrown at the execution time is termed as execution error.
  • :read-eval-result: An error thrown while reading the result of execution is categorized as read-eval-result error.
  • :print-eval-result: An error thrown while printing the result of execution is termed as print-eval-result error.Protocol extension by metadata

This release comes with a new option, :extend-via-metadata. When :extend-via-metadata is true, values can extend the protocols by adding metadata. The protocol implementations are first checked for direct definitions such as, defrecord, deftype, reify. Further,they are checked for metadata definitions, and then for external extensions such as, extend, extend-type, extend-protocol.


Clojure 1.10 comes with tap, a shared and globally accessible system used for distributing a series of informational or diagnostic values to a set of handler functions. It can be used as a better debug prn and for facilities like logging. The function tap> sends a value to the set of taps. The tap function may block (e.g. for streams) and would never impede calls to tap>. Indefinite blocking ly may cause tap values to drop.

Read string capture mode

This release comes with read+string function that not only mimics read but also captures the string that is read. It returns both the read value and the whitespace-trimmed read string. This function requires a LineNumberingPushbackReader.

Prepl (alpha)

Prepl, a new stream-based REPL, comes with structured output that is suitable for programmatic use. In prepl, forms are read from the reader and return data maps for the return value (if successful), output to *out* (possibly many), output to *err*(possibly many), or tap> values (possibly many).

Other functions in Clojure 1.10 include, io-prepl, a prepl bound to *in* and *out*, which works with the Clojure socket server and remote-prepl, a prepl that can be connected to a remote prepl over a socket

Datafy and nav

The clojure.datafy function features data transformation for objects. The datafy and nav functions can be used to transform and navigate through object graphs. datafy is still in alpha stage.

Major bug fixes

  • ASM regression has been fixed in this release.
  • In the previous release, there were issues with deprecated JDK APIs, which has been fixed.
  • The invalid bytecode generation for static interface method calls have been fixed.
  • Redundant key comparisons have been removed from HashCollisionNode.
  • This release reports correct line number for uncaught ExceptionInfo in clojure.test.

Many users have appreciated the efforts taken by the Clojure team for this project. According to most of the users, this release might prove to be a better foundation for developer tooling. Users are happy with the updated debug messages and bug fixes.

One user commented on HackerNews, “From the perspective of a (fairly large-scale at this point) app developer: I find it great that Clojure places such emphasis on backwards compatibility. The language has been designed by experienced and mature people and doesn’t go through “let’s throw everything out and start again” phases like so many other languages do.”  Though few users still prefer occasional updates instead so that they get better APIs.

Rich Hickey, the creator of Clojure language has been appreciated a lot for his efforts even by the non Clojurists. One of the users commented on HackerNews, “Rich’s writing, presentations, and example of overall conceptual discipline and maturity have helped me focus on the essentials in ways that I could not overstate. I’m glad (but not surprised) to see so much appreciation for him around here, even among non-Clojurists (like myself).”

Though REPLs use the ubiquitous paradigm of stdio streams and are efficient, their major downside is of mingling evaluation output with printing output (the “Print” step). Few users are linking this project with the unrepl and are confused if the design works for the projects.

Clojure is stable and it doesn’t have a static type system. Also, users are not happy with the changelog. However, this release has raised a few questions among the developer community. One of the big questions here is if PREPLs would replace remote APIs someday? It would be interesting to see if that really happens with the next set of Clojure releases.

Get more information about Clojure 1.10 on Clojure.

Read Next

ClojureCUDA 0.6.0 now supports CUDA 10

Clojure 1.10.0-beta1 is out!

Clojure for Domain-specific Languages – Design Concepts with Clojure