This post bears a similar message to a previous post: Assignments and Ifs
That post lays out a case against the feature provided by the Go programming language of inlining assignment statements into if statements. There are somewhat similar constructs in Clojure:
Let's experience a short programming adventure:
Ok, we'd like to invoke an external API to generate a token needed by our client-side code:
(if-let [token (external-api/generate-token (:customer-id user))]
(http/ok token)
(http/fail "Failure"))
Hmm, it would be nice to extract a separate binding for the id...
(if-let [id (:customer-id user)
token (external-api/generate-token id)]
(http/ok token)
(http/fail "Failure"))
Uh-oh, it doesn't compile because
if-let
only allows a single binding. Maybe define an outer let?
(let [id (:customer-id user)]
(if-let [token (external-api/generate-token id)]
(http/ok token)
(http/fail "Failure")))
Ugh, now there are two 'layers' of lets. That's a bit weird. Maybe combine both bindings in a single let and define a separate if statement?
(let [id (:customer-id user)
token (external-api/generate-token id)]
(if (some? token)
(http/ok token)
(http/fail "Failure")))
Ok, let's talk about the final code listing above. In that snippet the bindings and the logic have been decoupled. While this resulted in more code overall, I believe we are left with code that is easier to change and maintain.
"Good Design Is Easier to Change Than Bad Design." -The Pragmatic Programmer
My conclusion: The if-let and when-let forms are mini violations of SRP!
What do you think?