Rich Hickey gave a very thought-provoking talk at Clojure/conj 2018 called Maybe Not, where he mused on optionality and how we represent the absence of a value.
His talk covered many things, including how
complects both structure and optionality (and his thoughts on fixing that
in a future version of
clojure.spec), but his mention of
s/nilable was what
triggered an “ah-ha!” moment for me.
At World Singles Networks, we deal with a lot
of data in SQL (specifically in Percona’s fork of MySQL) and, in SQL, you represent
the absence of a value with
NULL in a column. Columns that represent optional
data must be declared as nullable and when you read data from them with
clojure.java.jdbc you get hash map
entries in the rows that have
nil values. If you’re using
describe your tables, rows, and columns, then you are going to have lots of
s/nilable specs – and now your “optionality” has been reified into
values, cast in the stone of your specs… which is clearly not an ideal situation!
This made me realize that
java.jdbc probably should just omit keys whose
values represent SQL
NULL. They are, after all, optional values rather than
truly nilable values.
That would be a potentially breaking change in behavior for
Sure, in most cases, if you have a hash map representing a row in a database
table, you’re not really going to care whether
(:col row) gives you
:col maps to
nil or because
row doesn’t contain
:col. There are
use cases where it matters:
contains?, row/column specs, tabular printing.
Along with changing the behavior of
NULL columns and
I have a lot of other changes that I’d like to apply to
java.jdbc, such as
automatically qualifying column keys with the table from which they came,
improving overall performance (by no longer converting
ResultSet objects to
sequences of hash maps), dramatically simplifying and streamlining the options
that are available (since many of them are very rarely used), and focusing on a
reducible-first API. All of which would be breaking changes.
I’ve learned a lot – about Clojure, idioms, and databases – over the seven
years that I’ve been maintaining
org.clojure/java.jdbc, and it is time for a
new namespace or perhaps even a completely new project, that offers a better
way to deal with SQL databases from Clojure! I’ll be writing a series of blog
posts about the differences I envisage between the current de facto standard
JDBC wrapper and where I’d like to go with this, so that I can get community
feedback on what should stay, what should change, and what should go. Stay tuned!