Open Collective
Open Collective
Loading
Clojure 1.11 support
Published on May 12, 2021 by Ambrose Bonnaire-Sergeant

Hi,

Recently I noticed this commit landed for Clojure 1.11--it enhances keyword argument destructuring to also accept a trailing map argument. This has a couple implications for Typed Clojure.

First, the type for keyword arguments is potentially even more interesting. For example, pass a map of type '{:a Str} you can pass (... :a "foo") or (... {:a "foo"}). This part is still on the drawing board, and similar libraries like clojure.spec and schema will also need to enhance their kw arguments types.

Second, the macroexpansion for `let` has now changed. This is relevant because Typed Clojure expands most macros before type checking, and because of the fact it looks really gnarly to type check!

It took several enhancements and bug fixes to support. The basic idea was to enhance the type checker's ability to infer the `count` of a collection based on calls to `next` and `seq`. eg., if a collection has a `next`, it's at least got 2 elements, but if it has `(every-pred (complement next) seq)` then it has exactly one element.

The money shot is that a branch that infers kw args as having exactly one element is unreachable, because kw args are always of even count. Well...this will change when we add the type I alluded to above.

But for now, typedclojure builds on Clojure 1.11.0-alpha1! It was quite fun solving this puzzle, and had me hacking all over the code base--the support for nthnext is especially cool and a joy to play with.

Ambrose