Clojure let you bind forms

I am trying to figure out how to tie closure bindings to cards. From my understanding, let there be a vector in which the first element is the symbol that I want to associate, followed by the value to which I want to associate it. So,

(let [a 1 b 2] a) 

will give a value of 1.

So, if I declare a map, for example

 (def people {:firstName "John" :lastName "Doe"}) 

And I want to bind the key firstName, then it will be the correct form for a simple "Hello man"

 (let [personName (:firstName people)] (str "hello " personName)) 

This works, however, on the Clojure website http://clojure.org/special_forms#binding-forms they show a different form that also works

 (let [{personName :firstName} people] (str "hello " personName)) 

Both code snippets work, and I understand why the first version works, but I got confused in the second syntax. Is it just syntactic sugar or a duplicate way of working and is another idiomatic than another?

+1
source share
2 answers

The last form is Restructuring map bindings . This is most useful if you want to bind several variables to different elements of the same map:

 (let [{firstName :firstName lastName :lastName address :address} people] (str "hello " firstName " " lastName ", I see you live at " address)) 

If you were to write this using the previous syntax, this would be:

 (let [firstName (:firstName people) lastName (:lastName people) address (:address people)] (str "hello " firstName " " lastName ", I see you live at " address)) 

As you can see, this eliminates the need to repeat people in each binding. And if the map is the result of a calculation, this avoids binding the variable to it so that you can repeat it.

Destructuring also allows you to lay out the binding structure in a format similar to the data structure that you are accessing. This makes it more idiomatic for complex structures.

+2
source

Just to be clear (and not too pedantic, hopefully) ...

IN

 (let [personName (:firstName people)] (str "hello " personName)) 

You do not bind the key :firstname to anything; you bind the identifier personName to the keyword application :firstname as a function of the people map.

IN

 (let [{personName :firstName} people] (str "hello " personName)) 

you destroy the people map by binding the personName identifier to its value in the key :firstname .


PS

This miracle is handled by the destructure function called by the let form. It may be helpful to see what he does. For instance,

 (destructure '[{personName :firstName} people]) ;[map__779 ; people ; map__779 ; (if ; (clojure.core/seq? map__779) ; (clojure.lang.PersistentHashMap/create (clojure.core/seq map__779)) ; map__779) ; personName ; (clojure.core/get map__779 :firstName)] 

I chose this idea here .

+2
source

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


All Articles