|
34 | 34 | ;;; Flow control operators are also extensible via macros, which allow the compiler to be extended by user code. We won't be discussing macros today, but you can read more about them at [Clojure.org](http://clojure.org/macros), [Clojure from the Ground Up](https://aphyr.com/posts/305-clojure-from-the-ground-up-macros), or [Clojure for the Brave and True](http://www.braveclojure.com/writing-macros/), among many other places. |
35 | 35 | ;;; |
36 | 36 | ;;; ## `if` |
37 | | -;;; ~\* explanation here \*~ |
| 37 | +;;; |
| 38 | +;;; `if` is the most important conditional expression - it consists of a condition, a "then", and an "else". `if` will only evaluate the branch selected by the conditional. |
38 | 39 | ;; ** |
39 | 40 |
|
40 | | -;; @@ |
41 | | -(ns cljlab.flowcontrol) |
42 | | -;; @@ |
43 | | - |
44 | 41 | ;; @@ |
45 | 42 | (str "2 is " (if (even? 2) "even" "odd")) |
46 | 43 | ;; @@ |
|
52 | 49 |
|
53 | 50 | ;; ** |
54 | 51 | ;;; ## Truthiness |
55 | | -;;; ~\* explanation here \*~ |
| 52 | +;;; |
| 53 | +;;; In Clojure, all values are "truthy" or not. The only "false" values are `false` and `nil` - all other values are "truthy". |
56 | 54 | ;; ** |
57 | 55 |
|
58 | 56 | ;; @@ |
|
85 | 83 |
|
86 | 84 | ;; ** |
87 | 85 | ;;; ## `if` and `do` |
88 | | -;;; ~\* explanation here \*~ |
| 86 | +;;; |
| 87 | +;;; The `if` only takes a single expression for the "then" and "else". Use do to create larger blocks that are a single expression. |
| 88 | +;;; |
| 89 | +;;; Note that the only reason to do this is if your bodies have side effects! (Why?) |
89 | 90 | ;; ** |
90 | 91 |
|
91 | 92 | ;; @@ |
|
98 | 99 |
|
99 | 100 | ;; ** |
100 | 101 | ;;; ## `when` |
101 | | -;;; ~\* explanation here \*~ |
| 102 | +;;; |
| 103 | +;;; `when` is a one-armed `if`. It checks a condition and then evaluates any number of statements as a body (so no `do` is required). The value of the last expression is returned. If the condition is false, nil is returned. |
| 104 | +;;; |
| 105 | +;;; `when` communicates to a reader that there is no "else" branch. |
102 | 106 | ;; ** |
103 | 107 |
|
104 | 108 | ;; @@ |
105 | | -;; example here |
| 109 | +(when (neg? x) |
| 110 | + (throw (RuntimeException. (str "x must be positive: " x)))) |
106 | 111 | ;; @@ |
107 | 112 |
|
108 | 113 | ;; ** |
109 | 114 | ;;; ## `cond` |
110 | | -;;; ~\* explanation here \*~ |
| 115 | +;;; |
| 116 | +;;; `cond` is a series of tests and expressions. Each test is evaluated in order and the expression is evaluated and returned for the first true test. |
111 | 117 | ;; ** |
112 | 118 |
|
113 | 119 | ;; @@ |
|
119 | 125 |
|
120 | 126 | ;; ** |
121 | 127 | ;;; ## `cond` and `else` |
122 | | -;;; ~\* explanation here \*~ |
| 128 | +;;; |
| 129 | +;;; If no test is satisfied, nil is returned. A common idiom is to use a final test of `:else`. Keywords (like `:else`) always evaluate to true so this will always be selected as a default. |
123 | 130 | ;; ** |
124 | 131 |
|
125 | 132 | ;; @@ |
|
132 | 139 |
|
133 | 140 | ;; ** |
134 | 141 | ;;; ## `case` |
135 | | -;;; ~\* explanation here \*~ |
| 142 | +;;; |
| 143 | +;;; `case` compares an argument to a series of values to find a match. This is done in constant (not linear) time! However, each value must be a compile-time literal (numbers, strings, keywords, etc). |
136 | 144 | ;; ** |
137 | 145 |
|
138 | 146 | ;; @@ |
|
146 | 154 | (foo 10) |
147 | 155 | ;; @@ |
148 | 156 |
|
| 157 | +;; ** |
| 158 | +;;; Unlike `cond`, `case` will throw an exception if no value matches: |
| 159 | +;; ** |
| 160 | + |
149 | 161 | ;; @@ |
150 | 162 | (foo 11) |
151 | 163 | ;; @@ |
152 | 164 |
|
153 | 165 | ;; ** |
154 | 166 | ;;; ## `case` with else-expression |
155 | | -;;; ~\* explanation here \*~ |
| 167 | +;;; |
| 168 | +;;; `case` can have a final trailing expression that will be evaluated if no test matches. |
156 | 169 | ;; ** |
157 | 170 |
|
158 | 171 | ;; @@ |
|
163 | 176 | "x isn't 5 or 10")) |
164 | 177 | ;; @@ |
165 | 178 |
|
166 | | -;; @@ |
167 | | -(foo 5) |
168 | | -;; @@ |
169 | | - |
170 | 179 | ;; @@ |
171 | 180 | (foo 10) |
172 | 181 | ;; @@ |
173 | 182 |
|
174 | 183 | ;; @@ |
175 | | -(foo 11) |
| 184 | +(foo 11) ;; falls into default instead of erroring |
176 | 185 | ;; @@ |
177 | 186 |
|
178 | 187 | ;; ** |
|
236 | 245 | ;;; * Sequences represent iteration as values |
237 | 246 | ;;; * Consumers can partially iterate |
238 | 247 | ;;; * Reducers represent iteration as function composition |
239 | | -;;; * New in Clojure 1.5, not convered here |
| 248 | +;;; * Added in Clojure 1.5, not convered here |
240 | 249 | ;;; |
241 | 250 | ;;; ### `loop` and `recur` |
242 | 251 | ;;; * Functional looping construct |
|
0 commit comments