There are at least two important use cases for let bindings:
First, using let , you can make the code clearer and shorter. If you have an expression that you use more than once, binding it in let very nice. Here is the part of the standard map function that uses let :
... (let [s1 (seq c1) s2 (seq c2)] (when (and s1 s2) (cons (f (first s1) (first s2)) (map f (rest s1) (rest s2))))))) ...
Even if you use an expression only once, it can be useful (for future code readers) to give it a semantically meaningful name.
Secondly, as Arthur said, if you want to use the value of an expression more than once, but only want it to be evaluated once, you cannot just print the entire expression twice: you need some kind of binding. That would be simply wasteful if you had a pure expression:
user=> (* (+ 3 2) (+ 3 2)) 25
but it actually changes the meaning of the program if the expression has side effects:
user=> (* (+ 3 (do (println "hi") 2)) (+ 3 (do (println "hi") 2))) hi hi 25 user=> (let [x (+ 3 (do (println "hi") 2))] (* xx)) hi 25
source share