{:check ["true"], :rank ["if" "cond"]}

Index

Branching in Clojure

If

If-else

Clojure provides the following form for if-else:

(if <cond>
    <if-expr>
    <else-expr>)

Note:

  • <if-expr> must be a single expression.
  • <else-expr> must be a single expression.
In [1]:
; Convert age to category

(def age 65)
(if (>= age 65)
    "Senior"
    "Not Senior")
Out[1]:
"Senior"
In [2]:
; A cleaner way
(let [age 65]
    (if (>= age 65)
        "Senior"
        "Not Senior"))
Out[2]:
"Senior"
In [5]:
; An even better way - make a function
(defn age->str [age]
    (if (>= age 65)
        "Senior"
        "Not Senior"))

(println (age->str 60))
(println (age->str 70))
;
Not Senior
Senior

Multiple expressions as ONE expression

What if we want to do:

(if <cond>
    <expr1>
    <expr2>
    ;; else
    <expr3>
    <expr4>)

You need to use the (do ...) form.

In [7]:
; Do accepts multiple expressions and evaluates all of them.
; But only the last expression's value is kept.
(do "Hello"
    "World"
    (str "Albert" "Einstein")
    (+ 1 1)
    (+ 1 2 3))
Out[7]:
6
In [8]:
; A good usage of `do` is to bundle
; println expressions in `if`

(if (>= age 65)
    (do (println "age" age ">=65")
        "Senior")
    (do (println "age" age "<65")
        "Not Senior"))
age 65 >=65
Out[8]:
"Senior"

Missing else part

(if <cond> <if-expr>)

is evaluation to

(if <cond> <if-expr> nil)
In [9]:
(if (>= age 65) "Senior")
Out[9]:
"Senior"
In [10]:
(if (>= age 90) "Old")
Out[10]:
nil

Boolean functions

  • (and ...)
  • (or ...)
  • (not ...)
In [11]:
; 65 <= age <= 70
(and (>= age 65) (<= age 70))
Out[11]:
true
In [12]:
; Senior or Child
(or (>= age 65) (<= age 12))
Out[12]:
true
In [13]:
; Not senior
(not (>= age 65))
Out[13]:
false

Cond

cond: A Better if

(cond <condition> <expression>
    <condition> <expression>
    ...)
In [7]:
; A pretty bad implementation
(defn age->category
    [age]
    (if (<= age 12)
        "Child"
        (if (<= age 21)
            "Teen"
            (if (< age 65)
                "Adult"
                "Senior"))))
Out[7]:
#'user/age->category
In [8]:
(println (age->category 23))
(println (age->category 31))
(println (age->category 5))
(println (age->category 100))
;
Adult
Adult
Child
Senior
In [9]:
; Cond to the rescue
(defn age->category
    [age]
    (cond 
        (<= age 12) "Child"
        (<= age 21) "Teen"
        (< age 65) "Adult"
        :else "Senior"))
Out[9]:
#'user/age->category
In [10]:
(println (age->category 23))
(println (age->category 31))
(println (age->category 5))
(println (age->category 100))
;
Adult
Adult
Child
Senior

References

References

  1. Programming Clojure: Section 2.6