Journal 2019.24 - spec and-, tools.deps.graph

I’ve fallen off the pace on these journals but here’s an update!

Spec 2

Most fresh in my head is some ongoing work on Spec 2. This week I added s/and-, which is a nonflowing variant of s/and. This variant does not pass a conformed value while validating or generating and instead validates each predicate against the candidate value, and conforms and gens only from the first predicate:

(s/def ::x (s/and- (s/cat :i1 int? :i2 int?) #(apply distinct? %)))
(s/valid? ::x [1 2])  ;; true
(s/valid? ::x [1 1])  ;; false

(s/conform ::x [1 2])
;;=> {:i1 1, :i2 2}
(s/explain ::x [1 1])
;; [1 1] - failed: (apply distinct? %) spec: :user/x

(gen/sample (s/gen ::x))
;;=> ((0 2) (-1 0) [0 -1] (-2 -1) (5 -5) (-8 15) (-3 1) [-1 -24] [-26 -1] [-116 -1])

(s/unform ::x {:i1 1, :i2 2})
;;=> (1 2)

We may swap the current s/and with this such that s/and would be nonflowing and the old s/and would be s/and->, still TBD.

Additionally, s/cat has always worked on any sequential collection, importantly vectors, lists, and seqs. However it only generated lists. That has now changed and it will generate both lists and vectors. You can combine with s/and- to narrow to only vector? or only seq?. There may still be some more changes in this area (particularly s/unform).

Some other minor bugs and enhancements - fixed s/form on fspecs, added vector-distinct-by to dynaload generator set, made gen/generator? public, fix allowing non-keyword keys to flow through s/keys.


If you’re interested in tools.deps, I did a talk about it Clojure/conj 2019. At the end of the talk I announced a new tool, tools.deps.graph which you can use to make graphs of your deps project dependencies or (for debugging purposes) trace the expansion process for your deps graph and what choices are made.

This tool can even drive from an expansion trace, which can now be generated by clj -Strace. More than anything, that’s useful for me to debug issues, but you can also just read the trace file directly - it contains an ordered list of the expansion steps, what lib is considered, whether it was included, and why or why not.

Some other features and fixes in recent tools.deps/clj releases include:

  • New alias options :deps and :paths, which are like :extra-deps and :extra-paths but actually indicate to replace, rather than append to the project deps and paths. This is primarily useful for tools that need their own classpath and don’t require using the project classpath.
  • Fix -Spom extra newline issue in newer JDKs (TDEPS-29)
  • Fix including pom dep resource directories in classpath (TDEPS-127)
  • Add support for Maven server http properties (needed for gitlab CI support) (TDEPS-140)


core.async had a couple releases. Deps were bumped up for tools.analyzer.jvm, tools.reader, etc. A new feature was added with the system property clojure.core.async.go-checking. When that’s set to true, if you use a blocking channel operation (>!!, <!!, alts!!, or alt!!) in a go block (importantly this can accidentally happen way down the call stack from a go), then an exception will be thrown. By default, this exception will kill the go block thread and get printed on stderror. You may have your own exception handling process that does otherwise or you can set the default uncaught thread exception handler if you want to log somewhere.

The pipeline function previously used the go block thread pool to implement the concurrent operations. That has been changed to match pipeline-blocking instead, which will use explicit threads to handle the N operations (previously N was unnecessarily bounded by the concurrency of the go pool).

Also, I have been working on a trio of doc pages for core.async - rationale (mostly from Rich’s release notes), a reference page (all new), and a guide (adopted from my original walkthrough). Not done yet.


Some other contrib lib updates:

  • Many contrib lib API docs were refreshed and some were created for the first time like tools.deps.alpha, tools.gitlibs, spec-alpha2, etc.
  • Released data.json 0.2.7 with a fix for DJSON-29 (throwing exceptions on various invalid json)
  • Released tools.namespace 0.3.1 with a fix for TNS-54 to fix issues on Java 9+ and bumps on java.classpath and tools.reader
  • Nicola Mometto released tools.analyzer.jvm 0.7.3 with bumped deps
  • Andy Fingerhut has been overhauling core.rrb-vector this fall and current version is 0.1.1
  • Sean Corfield released new versions of core.cache (0.8.2), core.memoize (0.8.2), (0.1.4)
  • and lots of minor updates on the build box and other infrastructure

Lots of updates on the site - companies, success stories, events, contributors, typos, fixes in reference docs, etc. Constant updates!

And did some analysis on some Clojure 1.11 ideas, nothing to report there, just laying some groundwork.

Other stuff I enjoyed this week…

A bit of old, some Bill Withers and a bit of new - new EP out from Theo Katzman.

Written on December 6, 2019