# Clojure +, +', and unchecked-add

# +

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

```clojure
(+ 1 2 3)
;;=> 6
```

Let’s introduce a handy function as we explore:

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

Let’s look at the largest supported `Long`:

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

What happens if we exceed it?

```clojure
(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:

```clojure
(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:

```clojure
(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
    

```clojure
(+ 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
```
