DEV Community

Cover image for Clojure 101 / destructuring
icncsx
icncsx

Posted on

Clojure 101 / destructuring

Destructuring is the process of unpacking items from collection types such as maps and vectors.

If you're coming from JavaScript land, you might have done something like this:

const [x,y] = [1,2] // vector destructuring

const { flavor } = { flavor: "cherry" taste: "sweet" } // map destructuring
Enter fullscreen mode Exit fullscreen mode

In Clojure, the syntax is similar!

Destructuring vectors/lists

By the way, if you're new to Clojure, think of vectors and lists as arrays [ ] and maps as non-null, non-array type objects, aka { }.

Ordered collection types such as vectors are naturally destructured by index.

(let [[flavor taste] 
      ["orange" "sour"]]
     (str "The " flavor " juice tastes " taste))
Enter fullscreen mode Exit fullscreen mode

This is what it would have looked like had we not used destructuring.

(let [my-juice ["orange", "sour"]
      flavor (first my-juice)
      taste (second my-juice)]
     (str "The " flavor " juice tastes " taste))
Enter fullscreen mode Exit fullscreen mode

Do you have a nested data structure you are working with? No problem.

(let [[flavor, [taste]] 
      ["orange" ["sour"]]]
     (str "The " flavor " juice tastes " taste))
Enter fullscreen mode Exit fullscreen mode

Destructuring maps

As you can imagine, maps are destructured by key. Let's introduce some Korean named variables to spice things up!

(let [{flavor :종류 taste :맛}
      {:종류 "orange" :맛 "sour"}]
     (str "The " flavor " juice tastes " taste))
Enter fullscreen mode Exit fullscreen mode

Most of the time you will probably want to give the same name of the binding as the key. With the advent of ES6, we use this pattern pretty gratuitously in JavaScript - especially when using a front-end library such as React or Vue.

const { taste } = { taste: "sour" }
console.log(taste); // "sour"
Enter fullscreen mode Exit fullscreen mode

In Clojure, we want to use the :keys directive, which will take a vector of keys that we want to pull.

(let [{:keys [flavor taste]}
      {:flavor "orange" :taste "sour"}]
     (str "The " flavor  " juice tastes " taste))
Enter fullscreen mode Exit fullscreen mode

Destructuring function arguments

Yes, you can also do this.

(defn sip-juice [{:keys [flavor taste]}]
  (str "The " flavor " juice tastes " taste))

(sip-juice {:flavor "orange" :taste "sour"})
Enter fullscreen mode Exit fullscreen mode

Admittedly, I'm getting a bit thirsty. I might grab a cup of orange juice. And yes, the orange juice tastes sour.

PS: If you're allergic to parentheses, I feel bad for you son, I got ninety nine problems but Clojure ain't one...

Warmly,
DH

Top comments (0)