In clojure terms, destructuring is taking apart a sequence and putting the pieces you care about into variables you can more easily work with. Destructuring involves square brackets that make it look like a vector, but it is really binding a variable from a given seq to a new variable. Let’s look at an example involving a function in Clojure.
1 2 3 4 5 |
(defn request-printer [[site page user]] (println (str "site=>" site "\npage=>" page "\nuser=>" user))) (defn -main [& args] (request-printer ["example.com" "clojure.html" "clojure dude"])) |
Notice the -main function has three variables in a vector: a site address, a web page, and a user name. It is much easier in the new function to unpackage these variables form the vector and bind them to variables that have meaningful names, and then use the names.
The result is as follows.
1 2 3 |
site=>example.com page=>clojure.html user=>clojure dude |
What if we have more values in the seq than values we intend to bind to? For example, below we added an additional index with the words “random stuff”.
1 2 3 4 5 |
(defn request-printer [[site page user]] (println (str "site=>" site "\npage=>" page "\nuser=>" user))) (defn -main [& args] (request-printer ["example.com" "clojure.html" "clojure dude" "random stuff"])) |
The additional parameter at the end is ignored. Only the three first variables are bound, in this example. The output is the same as the previous output where there was a one-to-one correspondence between the variables to bind and the incoming indices.
1 2 3 |
site=>example.com page=>clojure.html user=>clojure dude |
Now, what about cases where the variable you want to ignore is at the beginning or the middle of the needed variables?
This is a good time to use the ‘_’ (underscore). The underscore means, “Ignore the value at this index.” For example
1 2 3 4 5 |
(defn request-printer [[site page _ random]] (println (str "site=>" site "\npage=>" page "\nrandom=>" random))) (defn -main [& args] (request-printer ["example.com" "clojure.html" "clojure dude" "random stuff"])) |
Note the use of the underscore above to ignore the username and leave it unbound. The result is as follows.
1 2 3 |
site=>example.com page=>clojure.html random=>random stuff |
You can use as many underscores as you need to filter out indices that you want to ignore, as in this Clojure example.
1 2 3 4 5 |
(defn request-printer [[_ page _ random]] (println (str "page=>" page "\nrandom=>" random))) (defn -main [& args] (request-printer ["example.com" "clojure.html" "clojure dude" "random stuff"])) |
1 2 3 4 |
The resulting output is ... page=>clojure.html random=>random stuff |
For more details on Clojure destructuring, the official Clojure site has some great documentation on destructuring.