# Clojure Pitfalls: Part 1

Clojure is a great language, and as every language, it has some unobvious and strange things, which seem confusing.

Some of such things are gathered here. Most of them encountered by stupidity, docs misunderstanding, clojure specifics and procrastination.

### 1. Anybody home?

``````(contains? [10 20 30] 20) => false
``````

Surprised?

The issue here is `contains?` function checks if key (not a value!) is present in collection. For vector - key is index, and obviously there is no 20th element.

If you need to check if value is present in collection, use `some` predicate:

``````(some #(= % 20) [10 20 30]) => true
``````

Keep in mind this function works in linear time. If you need to call it often, build a set and use it as a function.

``````(def numbers (set [10 20 30]))
(numbers 20) => 20 ;; treated as true
(numbers 1) => nil ;; treated as false
``````

Note: if set contains `nil` or `false`, it won’t work. More discussion here.

### 2. Breaking the Law

You need stack. In clojure you can treat `list` like a stack.

``````;; take stack head
(peek '(1 2 3)) => 1

;; pop stack
(pop '(1 2 3)) => (2 3)

;; push item into stack
(cons 0 '(1 2 3)) => (0 1 2 3)
``````

Everything is fine. But if you call `pop` after `cons`

ClassCastException clojure.lang.Cons cannot be cast to clojure.lang.IPersistentStack

The problem is `cons` is type destructive operation.

``````(type '(1 2 3))            => clojure.lang.PersistentList
(type (cons 0 '(1 2 3)))   => clojure.lang.Cons
``````

And clearly, there is no `pop` defined for `Cons` type.

To preserve collection type, use `conj` function.

``````(type '(1 2 3))            => clojure.lang.PersistentList
(type (conj '(1 2 3) 0))   => clojure.lang.PersistentList
``````

### 3. Apples or Oranges? Part I

What’s the difference between `(last [1 2 3])` and `(last '(1 2 3))`?

Functionally there is no difference, both snippets return `3`

Moreover, from performance view there is no difference as well. Both snippets work in linear time. Linear. O(n). Even for vector.

What’s the difference between `(count [1 2 3])` and `(count '(1 2 3))`?

Much better here, `count` works in constant time for vector and linear for list. So, if you really need fast `last` for vector, use `count`.

``````;; 10M size vector
(def v (vec (range 1e7)))

(time (last v)) => 9999999
;; "Elapsed time: 1704.172859 msecs"

(time (get v (dec (count v)))) => 9999999
;; "Elapsed time: 0.087302 msecs"
``````

Huge difference.

Do not use vector specific functions to list. Also, consider using `mapv` instead of `map` when processing vectors.

### 4. Apples or Oranges? Part II

Everybody knows `reduce` and `apply` functions. Sometimes using choosing between them does not make any difference.

``````;; 100K numbers
(def N (repeatedly 1e6 #(rand-int 100)))

(time (reduce + N)) => 49503683
;; "Elapsed time: 311.496332 msecs"

(time (apply + N)) => 49503683
;; "Elapsed time: 339.624222 msecs"
``````

Sometimes it does.

``````;; 10K strings
(def S (repeatedly 1e5 (fn [] "1")))

(time (count(apply str S))) => 100000
;; "Elapsed time: 35.027218 msecs"

(time (count(reduce str S))) => 100000
;; "Elapsed time: 24249.845948 msecs"
``````

### 5. Refactor

Conditionals are horses of programming language.

``````(def status 500)
(= status 404)    "not_found.html"
(= status 500)    "server_fault.html"
(= status 200)    "index.html"
:else             "something_wrong.html")
``````

Pretty straightforward, but a piece `(= status %)` look ugly. Let’s refactor it a bit and avoid repetition with `condp`

``````(def status 500)
(condp = status
404    "not_found.html"
500    "server_fault.html"
200    "index.html"
:else  "something_wrong.html")
``````

Much better. Except we broke previous functionality. If pass invalid status (let’s say 201) we get an exception:

IllegalArgumentException No matching clause: 201

And that’s right: sugared keyword `:else` in `cond` behaves like regular clause in `condp` To make working solution, just remove `:else`.

``````(condp = status
404    "not_found.html"
500    "server_fault.html"
200    "index.html"
"something_wrong.html")
``````

### 6. Don’t trust your eyes

Get this portable, pure, thread-safe, well-documented, so beatiful and very awesome function:

``````(defn add [a b]
(+ a b))
``````

What’s wrong here? Is it really well-documented?

If you have sources, then yes, you see all documentation. But if you are library user you have no idea what function `add` might do.

``````(doc add)
; -------------------------
; ([a b])
;   nil
``````

Misplaced docstring. Transpose it with arglist.

``````(defn add
[a b]
(+ a b))

; -------------------------
; ([a b])
``````

Note: clojure lint tool eastwood is able to find this mistake.

### 7. It depends

There is less known, but useful feature dynamic binding

``````(def ^:dynamic *DEBUG* false)
``````

If your code depends on `*DEBUG*` binding, its behaviour can be modified without changing function definition

``````(defn square [a]
(when *DEBUG* (println "call square"))
(* a a))

(square 10) => 100

(binding [*DEBUG* true]
(square 10))
;; call square
=> 100
``````

If you have another value, that depends on dynamic binding, it is not dynamic.

``````(def ^:dynamic *DEBUG_PREFIX*
(if *DEBUG* "DEBUG=TRUE" "DEBUG=FALSE"))

(binding [*DEBUG* true]
*DEBUG_PREFIX*)
=> "DEBUG=FALSE"
``````

To fix that make it as a no-arg function. It will obtain dynamic binding right after the call.

``````(defn- debug-prefix []
(if *DEBUG* "DEBUG=TRUE" "DEBUG=FALSE"))

(binding [*DEBUG* true]
(debug-prefix))
=> "DEBUG=TRUE"
``````

There are three ways to access map value

``````(def m {:name "Quentin Tarantino"})

;; 1. By keyword
(:name m) => "Quentin Tarantino"

;; 2. By map as a function
(m :name) => "Quentin Tarantino"

;; 3. Using get
(get m :name) => "Quentin Tarantino"
``````

What version to use is a matter of style, because they are almost always interchangeble, but keep in mind some caveats.

``````(def m {"name" "Quentin Tarantino"})

("name" m) => ClassCastException java.lang.String cannot be cast to clojure.lang.IFn
``````

Second one is able to handle that, but instead it can throw NPE, when map is nil

``````(def m nil)

(m :name) => NullPointerException
``````

Using `get` we avoid these pros, and access become more obvious.

I prefer first version when using keyword explicitly, otherwise access via `get`

Thread macro is a convenient way to implement sequential processing.

Thread First `->` inserts previous result as a first argument for the next expression.

``````(-> (http/get URL)
(validate-status)
:body
:data
(first))
``````

Thread Last `->>` does the same, but insert previous result as a last argument

``````(->> (range 100)
(map square)
(filter even?)
(reduce +))
``````

If you need to insert previous result into specific position, wrap next expression to one-arg anonymous functions.

``````(->> (http/get URL)
(#(validate-status % :throw-exception))
:body
:data
(#(conj % [:guard])))
``````

### 10. Just Words

This one is not related to clojure, but interesting. Consider problem:

Find all words in a string

Pretty obvious, huh?

``````(re-seq #"\w+" "Hello, world!") =>
("Hello" "world")
``````

We don’t want numbers and underscore appear inside word

``````(re-seq #"\w+" "Hello, w_orld 1984!") =>
("Hello" "w_orld" "1984")
``````

Okay, use just letters:

``````(re-seq #"[a-zA-Z]+" "Hello, w_orld 1984!") =>
("Hello" "w" "orld")
``````

No, we don’t want broken words. Use `\b` word boundary regex.

``````(re-seq #"\b[a-zA-Z]+\b" "Hello, w_orld 1984!") =>
("Hello")
``````

Solved?

Not for ukrainian

``````(re-seq #"\b[a-zA-Z]+\b" "Привіт, світ 1984!") =>
nil
``````

And for every language which contains non-ascii letters in alphabet. Use unicode letter regexp `\p{L}` instead.

``````(re-seq #"\b\p{L}+\b" "Привіт, світ 1984!") =>
("Привіт" "світ")
``````
22 May 2014