upvote
The problem in my experience is that while nil is a perfectly reasonable default 9/10 times that 1/10 happens often enough and causes major problems that it is worth taking the extra few seconds to write it explicitly in the code to acknowledge that case and that you have checked that it is fine in the 9/10 cases or handle it in the 1/10 case.

I have seen multiple major production outages in Golang code because people accidentally read a non-existent map key and used the default value. As a funny bonus in one of those cases we were stumped when debugging because this code had tests, but the tests were also reading the default values out of the map and asserting that "" was in fact a valid textproto (it always is!) so silently testing nothing.

So even if defaults are useful 9/10 times that 1/10 is so painful and expensive that it isn't worth it in my experience. The time spent responding to, debugging and fixing those outages far, far outweighed the time saved by the convenient default values in the 9/10 times.

reply
For me: documentation at the "front door" of an interface, especially in that long moment before you decide to add a spec or Malli schema.
reply
deleted
reply
This is really the kind of thing you want to fail at compile time which isn’t real possible in a dynamic language like Clojure.
reply
Unless you use Typed Clojure, which is a library. https://github.com/typedclojure/typedclojure

I haven't used it, so I don't know its tradeoffs; but its docs say its types exist at compile time: https://github.com/clojure/core.typed/wiki/User-Guide

reply
Well it is possible - you can add a user macro that calls into clj-kondo (or anything actually) to check your codebase on compile

It just doesn't make much sense to do - most modern developers will be running static analysers through LSP or their editor (knowingly or not) continuously on code change so as to see those errors quicker than re-compiling the program

reply