Most examples have shown narrowing scope, but I expect you'd most likely use this if you realized you had a let
form inside an if
and realized you needed those bindings in the other branch of the if
form as well.
Let's say you're a troll and you've found a delicious-looking thief.
(defn eat-hobbit [hobbit]
(if (is-cooked? hobbit)
(eat! hobbit)
(let [is-fat (< too-greasy (:fat-content hobbit))]
(if is-fat
(eat! (deep-fry hobbit))
(eat! (saute hobbit))))))
You realize you should probably be making better health choices and not just eat every hobbit you come across, cooked or not, so you decide to decide whether or not to eat the hobbit in the first place based on how fatty it is. You need to know is-fat
before you decide to eat! So, you want to elevate that let
. Put the cursor after the binding vector in (let [is-fat ...]
and M-?
(and clean up whitespace with M-j M-q
):
(defn eat-hobbit [hobbit]
(let [is-fat (< too-greasy (:fat-content hobbit))]
(if (is-cooked? hobbit)
(eat! hobbit)
(if is-fat
(eat! (deep-fry hobbit))
(eat! (saute hobbit))))))
You're not DONE making better food choices yet, but now the binding is in the right scope to make better decisions.
Let's try it again. We should really ask if the hobbit is fat first, so put the cursor after (if is-fat
and M-?
(and cleanup with M-j M-q
again):
(defn eat-hobbit [hobbit]
(let [is-fat (< too-greasy (:fat-content hobbit))]
(if is-fat
(if (is-cooked? hobbit)
(eat! hobbit)
(eat! (deep-fry hobbit))
(eat! (saute hobbit))))))
Hmm. That's not quite VALID yet—there's an extra form in the if
—but it's very close to where we want to be. At this point, we can easily use the more common bindings of paredit to barf, transpose, and/or kill the extra form in the if
, depending on how sincere we are in our intentions towards healthy eating. We could also splice the two if
forms together for brevity.