Flow control expressions

Leap
Leap in Clojure
(defn- divides? [number divisor]
  (zero? (mod number divisor)))

(defn leap-year? [year]
  (if (divides? year 100)
    (divides? year 400)
    (divides? year 4)))

If

Clojure provides if, cond, condp and case expressions to control the flow of the program.

The if doesn't have an else if option, but it is not necessary here. We can use if once to check if the year is divisible by 100. If it is, then whether it is a leap year or not depends if it is divisible by 400. If it is not, then whether it is a leap year or not depends if it is divisible by 4.

(defn leap-year? [year]
  (if (divides? year 100)
    (divides? year 400)
    (divides? year 4)))

Cond

Another option is cond which allows for evaluating multiple conditions, similar to else if in other languages.

(defn leap-year? [year]
  (cond
    (divides? year 400) true
    (divides? year 100) false
    (divides? year 4) true
    :else false))

A very similar alternative is to use the condp macro, which takes a predicate and applies it to a series of test values and expected result pairs.

(defn leap-year? [year]
  (condp #(zero? (mod %2 %1)) year
    400 true
    100 false
    4   true
        false))

When using both cond and condp, the order matters, as the first true condition stops evaluating the list and determines the result.

Case

Finally, it is also possible to use case, but this solution is not popular.

(defn leap-year? [year]
  (case [(divides? year 400)
         (divides? year 100)
         (divides? year 4)
         ]
    [true true true]   true
    [false true true]  false
    [false false true] true
                       false))
13th Nov 2024 · Found it useful?