bindings => binding-form test
If test is true, evaluates then with binding-form bound to the value of
test, if not, yields else
user=> (defn sum-even-numbers [nums]
(if-let [nums (seq (filter even? nums))]
(reduce + nums)
"No even numbers found."))
#'user/sum-even-numbers
user=> (sum-even-numbers [1 3 5 7 9])
"No even numbers found."
user=> (sum-even-numbers [1 3 5 7 9 10 12])
22
user=> (if-let [x false y true]
"then"
"else")
java.lang.IllegalArgumentException: if-let requires exactly 2 forms in binding vector (NO_SOURCE_FILE:1)
user=> (defn if-let-demo [arg]
(if-let [x arg]
"then"
"else"))
user=> (if-let-demo 1) ; anything except nil/false
"then"
user=> (if-let-demo nil)
"else"
user=> (if-let-demo false)
"else"
; This macro is nice when you need to calculate something big. And you need
; to use the result but only when it's true:
(if-let [life (meaning-of-life 12)]
life
(if-let [origin (origin-of-life 1)]
origin
(if-let [shot (who-shot-jr 5)]
block-sol
42)))
; As you can see in the above example it will return the answer
; to the question only if the answer is not nil. If the answer
; is nil it will move to the next question. Until finally it
; gives up and returns 42.
(defmacro if-let
"bindings => binding-form test
If test is true, evaluates then with binding-form bound to the value of
test, if not, yields else"
{:added "1.0"}
([bindings then]
`(if-let ~bindings ~then nil))
([bindings then else & oldform]
(assert-args if-let
(and (vector? bindings) (nil? oldform)) "a vector for its binding"
(= 2 (count bindings)) "exactly 2 forms in binding vector")
(let [form (bindings 0) tst (bindings 1)]
`(let [temp# ~tst]
(if temp#
(let [~form temp#]
~then)
~else)))))
Comments top
1 comment(s) for if-let.
The difference between when-let and if-let is that when-let doesn't have an else clause and and also accepts multiple forms so you don't need to use a (do...).