When to use "if" and "when" in Clojure?
Solution 1
Use if
when you have exactly one truthy and one falsy case and you don't need an implicit do
block. In contrast, when
should be used when you only have to handle the truthy case and the implicit do
. There is no difference in speed, it's a matter of using the most idiomatic style.
(if (my-predicate? my-data)
(do-something my-data)
(do-something-else my-data))
(when (my-predicate? my-data)
(do-something my-data)
(do-something-additionally my-data))
In the if
case, only do-something
will be run if my-predicate?
returns a truthy result, whereas in the when
case, both do-something
and do-something-additionally
are executed.
Solution 2
Use if
when you have two different expressions: for true
clause and for false
clause.
when
and when-not
are useful in two cases:
- when you want to perform one or several (implicit
do
helps here) non-pure operations conditionally; - when you want to evaluate something when some predicate evaluates to
true
(orfalse
in case ofwhen-not
), and returnnil
in opposite case.
only difference is the return of false or nil
There is no major difference between false
and nil
, as the both evaluate to false
in logical context.
Alonzorz
Updated on June 12, 2022Comments
-
Alonzorz almost 2 years
When is one better than the other? Is one faster than the other or does the only difference is the return of false or nil?
-
Mars over 9 yearsI've noticed a stylistic difference in use of
when
in Clojure and Common Lisp. In CL, some people consider it bad to usewhen
if you care about the return value when the test fails; in that case you should explicitly returnnil
in the last clause of anif
. It makes sense that it's common to usewhen
in Clojure in the same situation, since most code is purely functional in Clojure: return values are rarely ignored. If Clojure programmers followed the CL convention,when
would rarely be used in purely functional code. (Occasionallynil
vs.false
matters.) -
Mark Karpov over 9 years@Mars, it is interesting, is there real reason for coexistence of
false
andnil
in Clojure? I can think of no situation whenfalse
could do something thatnil
couldn't. -
Mars over 9 years
-
Mars over 9 yearsAlso: Because
nil
means something like "empty sequence" as well as false,next
andrest
have meaning when applied tonil
, but throw exceptions when applied tofalse
. Other interesting uses ofnil
includesome
, which can function like a predicate because it returns nil on failure, but isn't really a predicate (therefore it has no "?" in it's name), andkeep
(see doc page). However, I don't fully understand why Clojure should have bothnil
andfalse
. -
schaueho over 9 years@Mars In CL, the recommendation is basically the same as for Clojure, cf. google-styleguide.googlecode.com/svn/trunk/… and cs.cmu.edu/Groups/AI/html/faqs/lang/lisp/part1/faq-doc-4.html. From the latter: Never use a 2-argument IF or a 3-argument
IF
with a second argument ofNIL
unless you want to emphasize the return value; useWHEN
andUNLESS
instead. You will want to emphasize the return value when the IF clause is embedded within aSETQ
, such as(SETQ X (IF (EQ Y Z) 2 NIL))
. -
damonh about 7 yearsWhat if I only have to handle the true case, and no implicit
do
is needed, which is more conventional to use in this case? -
schaueho about 7 yearsUse
when
. Thedo
part is an additional good reason to preferwhen
overif
, not a necessary precondition.