I am still trying to increase my lisp reading speed. As such, my first inclination is to try and name everything (usually in let bindings) to make up for my slow comprehension. In examples online, there is always a mix of some things being bound, and others just being used in place.
Like this silly s-expression to parse (1 2 4 + 4) could be written with let bindings:
(let [first-nums (take (- (count args) 2) args)
last-num (last args)
fun (nth args (- (count args) 2))]
(reduce fun (conj first-nums last-num))))
Or without:
(reduce (nth args (- (count args) 2))
(conj (take (- (count args) 2) args)
(last args)))))
On the one hand, giving good domain names to “concepts” is something that I believe very much when working in the c-style languages, and even though the scope of let is very strictly defined, it still feels very anti-functional to be binding state.
What is your criteria for when to use bindings?
Giving things names is fine. It helps making things self-documenting. There is nothing wrong with it. If things are too obvious one might want to get rid of it sometimes:
Above does not add much to the expression
(+ 12 30). But if you want to document domain values, then instead ofbetter write
One question which remains is this: when you have a data structure, you want to use parts of it in some way and you want to give these parts temporary names – how to do that?
In your example,
LETintroduces the names and you provide hand-written code to extract the values.Slighty ‘better’ could be a more descriptive approach:
Something like the above would make sense if you have to deal with such patterns often in the code. It would make the code more declarative.