Skip to main content

Command Palette

Search for a command to run...

Clojure +, +', and unchecked-add

Updated
1 min read
Clojure +, +', and unchecked-add

+

In Clojure core there’s a handy function, +. I’ll bet you know what it does:

(+ 1 2 3)
;;=> 6

Let’s introduce a handy function as we explore:

(defn value-and-type
  [& args]
  (map (juxt identity type) args))

Let’s look at the largest supported Long:

(value-and-type Long/MAX_VALUE)
;;=> ([9223372036854775807 java.lang.Long])

What happens if we exceed it?

(value-and-type (+ 1 Long/MAX_VALUE))
;;=> Execution error (ArithmeticException) at java.lang.Math/addExact (Math.java:931).
;;   long overflow

It throws!

+'

The fact that + throws on overflow is why +' exists:

(value-and-type (+' 1 Long/MAX_VALUE))
;;=> ([9223372036854775808N
;;     clojure.lang.BigInt])

Instead of overflowing, it promoted from a Long to a BigInt. In addition to +', there are -', *', inc', and dec'.

unchecked-add

Now for unchecked-add. Notice how it wraps around:

(value-and-type
 Long/MIN_VALUE
 (unchecked-add Long/MAX_VALUE 1))
;;=> ([-9223372036854775808 java.lang.Long]
;;    [-9223372036854775808 java.lang.Long])

In addition to unchecked-add, there are unchecked-subtract, unchecked-multiply, unchecked-inc, unchecked-dec, and unchecked-negate.

Summary

If you’re dealing with a Long, on overflow:

  • + throws

  • +' promotes to BigInt

  • unchecked-add wraps around

(+ Long/MAX_VALUE 1)
;;=> Execution error (ArithmeticException) at java.lang.Math/addExact (Math.java:931).
;;   long overflow
(+' Long/MAX_VALUE 1)
;;=> 9223372036854775808N
(unchecked-add Long/MAX_VALUE 1)
;;=> -9223372036854775808