Head into Clojure – Part 5: Control statements

Ok, we can use base types know the difference between collections and sequences ( if you do be sure to tell me ! ) and we can write some basic functions and use map/reduce/filter to play around with collections.

Hopefully you have also upgraded from the basic Clojure REPL to Leiningen one, and are reaping the benefits of uber productivity

Now its time to get real and start writing some real functions, more than a single line and with ability to control flow through the function

;; if statement

(defn is_true? [x] (if (true? x) "yes" "no"))                   ;; Example of if statement   
(is_true? false)                                                ;; results in "no"

;; cond statements

(defn is_positive? [x]                                          ;; Define a function that gives a string value for a numbers positivity
  (> x 0) "positive"                                            
  (< x 0) "negative"
  :else   "zero" ))                                             ;; Optional default catch all others

(is_positive? 3)                                                ;; Results in "positive"

;; case statements

(defn number_str [x]
  (case x
     1 "One"
     2 "Two"
     3 "Three"
     4 "Four"
     5 "Five"
     "Too big"))

(number_str 1)                                                   ;; Results in "One"
(number_str 4)                                                   ;; Results in "Four"
(number_str 10)                                                  ;; Results in "Too big"

;; do statements

;; Do evaluates a sequence of expressions in order, the result of the expression is the value of the last
;; expression in the list
(def x 3)
    (println "Starting")
    (+ x 1)
    (inc x)
    (println "Stopping")
    x )
;; Results in the following output, but why ?
;; This is a classic example of immutable data, while 2 statements in the middle apply operations to the variable x
;; but these operations only return values, they do not change the value of x in the expressions
;; This is one of the key facets of functional programming

;; loop/recur

(loop [x 10]                                                     ;; Entry point 
  (when (> x 1)
    (println x)
    (recur (- x 2))))                                            ;; Recursive call into the call stack with updated 
                                                                 ;; parameters

;; List Comprehension

(for [x (range 100)] x)                                          ;; Create a list 0 to 99

(for [x (range 100)] (* x x))                                    ;; Create a list by iterating through each number
                                                                 ;; 0 - 99 and multiplying it by itself

(for [x (range 100)] (even? x))                                  ;; Create a list of booleans representing whether
                                                                 ;; each number between 0 and 99 is even or odd

(for [a (range 100)                                              ;; Nested loop that creates a list of vectors
      b (range 100 200)                                          ;; each vector is created from a nest loop
    [a b]                                                        ;; For each a 0 - 99, iterate through b 100-199

(for [a (range 100)                                              ;; Nested loop that creates a list if vectors
      b (range 100 200)                                          ;; as above, but exits when a * b > 1000
      :while (< (* a b) 1000)] 
    [a b]