Clojure Deref (Oct 8, 2021)

08 October 2021
Alex Miller

Welcome to the Clojure Deref! This is a weekly link/news roundup for the Clojure ecosystem. (@ClojureDeref RSS)

Last week was a bit of a Deref holiday as your host was otherwise occupied running the Strange Loop conference (in-person)! It was really great to see so many familiar friends and (masked) faces at a conference again. As I said during the opener, turns out it actually is the people you meet along the way that make it all worthwhile. :) Can’t wait to see you all at a Clojure conference in the future.

In the core

Fogus has been working through the spec-related updates for the change in 1.11.0-alpha1 to support a trailing map in calls to kwarg functions (typically spec’ed with keys* specs). This was not something we were that worried about initially, but it has turned out to be a far more intricate puzzle than we imagined.

For example, you might have a function and a spec:

;; opts can be kwarg :a or :b
(defn config [name & opts] ...)
;; (config "a-name" :a 100 :b 200)

;; spec options with keys*
(s/def ::a int?)
(s/def ::b int?)
(s/fdef config
  :args (s/cat :name string? :opts (s/keys* :opt-un [::a ::b])))

;; now a valid call, but fails the spec when instrumented
(stest/instrument `config)
(config "a-name" {:a 100 :b 200})
Execution error - invalid arguments to user/config at (REPL:1).
{:a 100, :b 200} - failed: keyword? at: [:opts :clojure.spec.alpha/k]

The initial thought was just to make keys* spec smarter, but really on close examination this is problematic. keys* can be used in multiple contexts - in a custom data structure with its own syntax, in macro definitions, or in function definitions. In the first couple cases, this is effectively language created by a designer and adding newly allowed cases is probably wrong (some good examples can be built from the ns specs). On the other side, we could leave keys* alone and add a new spec that you could "opt into" when you want this (but then everyone has to update their function specs). But we’re trying to find a middle path by hooking instrument for functions to transform the input before it is checked with keys*, so that particular case continues to work automatically in 1.11 with existing specs (and other uses are not affected). Anyhow, that work is getting close.

I’ve been working on several things, but one ongoing thing we’re exploring is some way to surface some of the static methods in java.lang.Math etc so that they are both fast and more "visible". At the moment I’m going down the path of generating a namespace by reflecting Math - originally as a dynamic thing, now looking more at code gen pre build. Still not sure exactly where this will end up. I also spent a lot of time in the last couple weeks diving into a new batch of jiras and each of those is its own little world and I will talk more about some of those as they move through the pipeline.

Videos and podcasts

Libraries and Tools

New releases and tools this week:

  • deja-fu - Lightweight ClojureScript local time/date library

  • neil - A CLI which adds common features to your #clojure deps.edn projects.

  • lrsql - A SQL-based Learning Record Store

  • colossal-squuid - Library for generating sequential UUIDs, or SQUUIDs

  • nvd-clojure 1.7.0 - National Vulnerability Database dependency-checker plugin for Leiningen

  • sci 0.2.7 - Configurable Clojure interpreter suitable for scripting and Clojure DSLs

  • clojure-lsp 2021.09.30-15.28.01 - A Language Server for Clojure(script)

  • Calva 2.0.214 - Calva is an integrated REPL powered environment for enjoyable and productive Clojure and ClojureScript development in Visual Studio Code.

  • secret-keeper 0.3.61 - A Clojure(Script) library for keeping your secrets under control

  • api-diff - Compare two mvn libraries or two directories for breaking API changes and deprecations.

  • ruuter - A tiny, zero-dependency HTTP router

  • vim-iced 3.7.0 - Clojure Interactive Development Environment for Vim8/Neovim

  • deps.clj v0.0.19 - A faithful port of the clojure CLI bash script to Clojure.

  • clj-kondo 2021.09.25 - A linter for Clojure code that sparks joy

  • babashka 0.6.2 - Native, fast starting Clojure interpreter for scripting

  • c4k-jira - c4k-jira provides a k8s deployment for jira

  • vim-iced 3.7.0 - Clojure Interactive Development Environment for Vim8/Neovim

  • next-jdbc 1.2.731 - A modern low-level Clojure wrapper for JDBC-based access to databases

  • honeysql 2.1.818 - Turn Clojure data structures into SQL