When to use let vs. if-let in Clojure

14,928

Solution 1

I guess if-let 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.

Solution 2

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]
Share:
14,928
Arthur Ulfeldt
Author by

Arthur Ulfeldt

TLDR Clojure, Docker, Linux, Security, Teaching. https://www.linkedin.com/learning/instructors/arthur-ulfeldt?u=2125562 contacting me: If you are interested in learning clojure you can call me at 1-219-CLOJURE For general Clojure chatting you can find me in IRC #clojure on freenode (thearthur) email < my first name >@< my last name >.com Interests I'm a Clojure and Linux nut with a long standing interest in virtual machines and fancy networking of all sorts. At work I write Clojure Web apps and such full time for yummly.com as well as writing "cloud" deployment systems (some would call it "devops", though I think that term is worn out by now). At home I play with Clojure, Linux, docker, Amateur Radio, and Cryptography quite a bit. I have been a functional programming enthusiast for many years and get quite a lot of personal satisfaction every time i use anything map-reduce related. I am interested in network security related projects and people that are trying to steer the world away from "the corporate castle" metaphor. If you have or are thinking about such a project I would love to hear from you. note for recruiters: I would like to politely decline any positions you might have with "devops" or "language-name engineer" in the title. PS: KE6DRD

Updated on June 23, 2022

Comments

  • Arthur Ulfeldt
    Arthur Ulfeldt almost 2 years

    When does using if-let rather than let make code look better and does it have any performance impact?