7/6/2026 at 3:12:57 PM
This is a case I never really thought about - if the key is missing today you'll get nil as the value and since Clojure is a nil punning language it usually does sensible behaviour in your programI know this sounds unreliable but in practise I like a language that defaults to pragmatic code paths so I don't have to stay up at night imagining a million code paths
This adds a throwing codepath which is quite drastic so I'm glad people don't build this into programs everywhere - I'd be nice to hear what the team imagine as the use case for this
Normally for correctness I'd like to see specs at the boundaries for programs and different test suites for internal behaviours
by slifin
7/6/2026 at 4:45:38 PM
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.
by kevincox
7/6/2026 at 9:44:13 PM
defaults are a different thing to nil punningSo nil will have had special consideration in Clojure core functions
That doesn't mean it doesn't crash either it will absolutely be unhappy with nils in your math
nil is usually unexpected in test outputs or at the very least an unhappy path
In terms of debugging that's why I can't quit this language flowstorm let's me visually step through what happened line by line, backwards, forwards, programmatically - whatever
Languages should be competing against each other by their best time travel debugger it just completely removes the need for guesswork
by slifin
7/6/2026 at 4:49:28 PM
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.by xoxolian
7/6/2026 at 6:16:06 PM
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.by jimbokun
7/6/2026 at 6:55:38 PM
Well it is possible - you can add a user macro that calls into clj-kondo (or anything actually) to check your codebase on compileIt 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
by slifin
7/6/2026 at 6:53:38 PM
Unless you use Typed Clojure, which is a library. https://github.com/typedclojure/typedclojureI 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
by xoxolian
7/6/2026 at 8:39:18 PM
> ... if the key is missing today you'll get nil as the value and since Clojure is a nil punning language it usually does sensible behaviour in your programAnd that is still doable AIUI: they're optional checked keys. The doc describing them makes the distinction between required and non-required keys.
Arguably we already had those: I religiously use spec'ed maps in my Clojure since a great many years (and Clojure spec is still in alpha, but "alpha" in Clojure land basically means: "more stable and less likely to change than any feature in any other language" and I'm only slightly exaggerating here).
In my case I use good old defn-spec (form Orchestra but YMMV) instead of defn. And my maps are (partially) spec'ed, using spec'ed keys (as well as any other non-spec'ed key I feel like using). Sure it's only runtime checks but it's really great.
You get to both have the extensibility (you can for example add keys that don't exist yet later on without changing any of your specs) and you can specify which keys are required.
For there is such a thing as maps where you know that this and that key must always be there.
I don't think it's an issue to have optional checked keys. Especially not when you can mix both required and non-required keys in the same map.
by TacticalCoder