Clojure treats `nil` differently than ClojureScript does (can't do arithmetic with a Clj null; can with a Cljs' null)

Clojure treats nils differently from ClojureScript. For example, you can inc a nil in ClojureScript but not Clojure. I watched Jacek’s course (video #7) and saw him use update on an empty map with an unused key and inc: basically (update {} :id inc). It returned the map with the id and 1 (from {} to something like {:id 1}). Confused about this, I learned about updates nil-adding feature and wondered how inc handled `nil.

According to the update docs, if the key doesn’t exist, it creates one with the value, nil before applying the given function. I tested this out in Clojure and got a Dirk NullPointerException. I thought it might be something with the Reagent atom, so I plopped a map in an r/atom and an atom:

(def t (r/atom {}))
(def a (atom {}))
(swap! t update :a inc)
(swap! a update :a inc)
(println @t)                  ;;=> {:a 1}
(println @a)                  ;;=> {:a 1}
(println (update {} :a inc))  ;;=> {:a 1}

swap!ing with an update and inc worked on both. update and inc worked on an empty map outside of it, too. I tried it again in Clojure: NPException.

The contrast docs on nil explain that nil is Java’s null in Clj and JS’s null in Cljs (as expected). This means in JavaScript, you can perform arithmetic from nulls. In Java, you cannot: null + 1 ;;=> 1.