Structuring the Code

Web Development with Clojure, Third Edition — by Dmitri Sotnikov, Scot Brown (74 / 107)

The Pragmatic Programmers
The Pragmatic Programmers

--

👈 Being Lazy | TOC | Destructuring Data 👉

One nontrivial difference between Clojure and imperative languages is the way the code is structured. In imperative style, it’s a common pattern to declare a shared mutable variable and modify it by passing it different functions. Each time we access the memory location, we see the result of the code that previously worked with it. For example, if we have a list of integers and we wish to square each one and then print the even ones, the following Python code would be perfectly valid:

​ l = list(range(1, 6))

​ ​for​ i, val ​in​ enumerate(l) :
​ l[i] = val * val

​ ​for​ i ​in​ l :
​ ​if​ i % 2 == 0 :
​ ​print​(i)

In Clojure this interaction has to be made explicit. Instead of creating a shared memory location and then having different functions access it sequentially, we chain functions together and pipe the input through them:

​ (​run!​ println
​ (filter #(= (​mod​ % 2) 0)
​ (map #(* % %) (range 1 6))))

Or, as we’ve covered, we could use the ->> macro to flatten the operations:

​ (​->>​ (range 1 6)
​ (map #(* % %))
​ (filter #(= (​mod​ % 2) 0))
​ (​run!​ println))

Each function returns a new value instead of modifying the existing data in place. You may think that this can get…

--

--

The Pragmatic Programmers
The Pragmatic Programmers

We create timely, practical books and learning resources on classic and cutting-edge topics to help you practice your craft and accelerate your career.