When does using if-let
rather than let
make code look better and does it have any performance impact?
views:
479answers:
2I guess it should be used when you'd like to reference an if
condition's value in the "then
" part of the code:
i.e. instead of
(let [result :foo]
(if result
(do-something-with result)
(do-something-else)))
you write:
(if-let [result :foo]
(do-something-with result)
(do-something-else))
which is a little neater, and saves you indenting a further level. As far as efficiency goes, you can see that the macro expansion doesn't add much overhead:
(clojure.core/let [temp__4804__auto__ :foo]
(if temp__4804__auto__
(clojure.core/let [result temp__4804__auto__]
(do-something-with result))
(do-something-else)))
This also illustrates that the binding can't be referred to in the "else
" part of the code.
A good use case for if-let
is to remove the need to use anaphora. For example, the Arc programming language provides a macro called aif
that allows you to bind a special variable named it
within the body of an if
form when a given expression evaluates to logical true. We can create the same thing in Clojure:
(defmacro aif [expr & body]
`(let [~'it ~expr] (if ~'it (do ~@body))))
(aif 42 (println it))
; 42
This is fine and good, except that anaphora do not nest, but if-let
does:
(aif 42 (aif 38 [it it]))
;=> [38 38]
(aif 42 [it (aif 38 it)])
;=> [42 38]
(if-let [x 42] (if-let [y 38] [x y]))
;=> [42 38]