What does destructuring in Clojure mean?

I am Java and learn clojure.

What exactly destroys in clojure?

I see this blog saying:

The simplest example of destructuring is the assignment of vector values.

user=> (def point [5 7]) #'user/point user=> (let [[xy] point] (println "x:" x "y:" y)) x: 5 y: 7 

what did he mean by assigning the values of a vector ? What is its use?

Thank you in advance

+6
source share
6 answers

point is a variable containing a vector of values. [xy] is a vector of variable names.

When you assign point - [xy] , destructuring means that each of the variables is assigned a corresponding element in the value.

This is just an easier way to write:

 (let [x (nth point 0) y (nth point 1)] (println "x:" x "y:" y)) 

See Clojure's ability to bind forms for another way to use destructuring.

+2
source

The term "Destructuring" sounds harder than him.

This is similar to visually matching shapes to shapes. For instance:

 (def nums [1 2 3 4 5 6]) (let [[abc & others] nums] ;; do something ) Imagine the effect of the let binding as: 1 2 3 4 5 6 | | | ( ) vvvv [abc & others] ;; Now we can use a, b, c, others, and of course nums, ;; inside the let binding: user=> (let [[abc & others] nums] (println a) (println b) (println c) (println others) (println nums)) 1 2 3 (4 5 6) [1 2 3 4 5 6] 

The goal is to briefly identify the elements of the collection for use within the binding region or let function (ie, within the “lexical region”).

Why "short"? Well, without breaking, let binding will look like this:

 (let [a (nth nums 0) ;; or (first nums) b (nth nums 1) ;; or (second nums) c (nth nums 2) others (drop 3 nums)] ;; do something ) 

This illustrates the basic idea. There are many details (ifs and buts, dos and don'ts), and this is worth reading further in depth. Here are a few resources that explain more, with examples:

My personal favorite: Jay Fields post on Clojure Destructuring: http://blog.jayfields.com/2010/07/clojure-destructuring.html

A gentle introduction to destruction, by Braveclojure: http://www.braveclojure.com/do-things/#3_3_3__Destructuring

+2
source

This means creating an image of the structure of some data with symbols

 ((fn [[d [s [_ _]]]] (apply str (concat (take 2 (name d)) (butlast (name s)) (drop 7 (name d))) )) '(describing (structure (of data)))) => "destructuring" ((fn [[de _ _ _ _ _ ing _ _ _ _ _ structure & etc]] [destructuring]) "describing the structure of data") => [\d \e \s \t \r \u \c \t \u \r \i \n \g] 

Paste these ^ examples into REPL and play with them to see how it works.

+2
source

Destructuring associates a name template with a complex object, binding each name to the corresponding part of the object.

To bind to a sequence, you represent a vector of names. For instance...

 (let [[xy] (list 5 7)] ... ) 

... is equivalent

 (let [x 5, y 7] ... ) 

To snap to a map or vector by searching by index, you present a map of name-key pairs. For instance...

 (let [{x 0, y 1} [5 7]] ... ) 

... is equivalent to both of the above.

As already mentioned, you can find a full description of this powerful mechanism here .

0
source

used to indicate the components of the data structure and obtain their values.

Say you want to have a human structure. In java you have to go all the way to create a class with constructors, getters and setters for various fields such as name, age, height, etc.

In Clojure, you can skip the “ceremony” and just have a vector with three slots, first for the name, than for age and for the last. Now you can simply name these "components" and get their values, for example:

 (def person ["Fred" 30 180]) (let [[name age height] person] (println name age height)) ;; will print: Fred 30 180 

ps - there are better ways to make a "person" in Clojure (for example, recordings, etc.), this is just an example to understand what destructuring is.

0
source

Destructuring is a convenient feature that makes it easy to create local bindings (not variables!) By separating complex data structures (seq-ables, such as vectors or associations, such as hash maps), as described here .

Take the following example:

 (let [v [1 2 3 4 5 6] v_0 (first v) v_1 (nth v 1) v_rest (drop 2 v) m {:a 1 :b 2} m_a (get m :a) m_b (get m :b) m_default (get m :c "DEFAULT")] (println v, v_0, v_1, v_rest, m, m_a, m_b, m_default)) 

Then, the above code can be simplified using destructive bindings such as:

 (let [[v_0 v_1 & v_rest :as v] [1 2 3 4 5 6] {m_a :a m_b :b m_default :c :or {m_default "DEFAULT"} :as m} {:a 1 :b 2}] (println v, v_0, v_1, v_rest, m, m_a, m_b, m_default)) 

Destruction patterns can be used in let bindings and functional parameters ( fn , defn , letfn , etc.), as well as in macro returns let bindings containing such destruction patterns.

One important use of the if-let and when-let macros should be noted. The if always evaluated in its entirety, even if the destructed bindings themselves are evaluated as nil :

 (if-let [{:keys [ab]} {:c 1 :d 2}] (println ab) (println "Not this one")) 
0
source

Source: https://habr.com/ru/post/971499/


All Articles