`if`

`cond`

- Boolean logic

“Flow control” is the programming term for deciding how to react to a given circumstance. We make decisions like this all the time.

Ifit’s a nice day out,thenwe should visit the park;otherwisewe should stay inside and play board games.Ifyour car’s tank is empty,thenyou should visit a gas station;otherwiseyou should continue to your destination.

Software is also full of these decisions.

Ifthe user’s input is valid,thenwe should save their data;otherwisewe show an error message. The common pattern here is that you test some condition and react differently based on whether the condition istrueorfalse.

`if`

In Clojure, the most basic tool we have for the flow control is the

`if`

operator. It allows you to choose between two options depending upon a condition.

Reference: Conditional

`if`

```
(if (< age legal-drinking-age)
["water" "soda"]
["water" "soda" "beer" "wine"])
```

```
(if conditional-expression
expression-to-evaluate-when-true
expression-to-evaluate-when-false)
```

When testing the truth of an expression, Clojure considers the values

`nil`

and`false`

to be false and everything else to be true. Here are some examples:

Reference: Truthiness

```
(if "anything other than nil or false is considered true"
"A string is considered true"
"A string is not considered true")
;=> "A string is considered true"
```

```
(if nil
"nil is considered true"
"nil is not considered true")
;=> "nil is not considered true"
```

```
(if (get {:a 1} :b)
"expressions which evaluate to nil are considered true"
"expressions which evaluate to nil are not considered true")
;=> "expressions which evaluate to nil are not considered true"
```

- write a function
`ordinal`

that takes a number`n`

as an argument - start from the template on this slide
- if
`n`

equals`1`

, then the function should return`"1st"`

, otherwise it should return the number +`"th"`

- you will have to use the
`str`

function - don’t worry yet about “2nd” or “3rd”

```
(defn ordinal [n]
(if ;; condition
;; then
;; else
))
```

```
;; usage of ordinal function
(ordinal 1) ;=> "1st"
(ordinal 5) ;=> "5th"
```

- extend the
`ordinal`

function to correctly generate “2nd” and “3rd” - hint: you can use an
`if`

inside another`if`

```
;; usage of the new ordinal function
(ordinal 1) ;=> "1st"
(ordinal 2) ;=> "2nd"
(ordinal 3) ;=> "3rd"
(ordinal 4) ;=> "4th"
```

`cond`

The

`if`

operator takes only one predicate. When we want to use multiple predicates,`if`

is not a good option. We have to write nested, nested, … and nested`if`

conditions. To branch to multiple situations,`cond`

operator works well.

Reference: Conditional

`cond`

```
(if (= n 1)
"1st"
(if (= n 2)
"2nd"
(if (= n 3)
"3rd"
(str n "th"))))
```

In this case `cond`

comes in handy.

```
(cond
(= n 1) "1st"
(= n 2) "2nd"
(= n 3) "3rd"
:else (str n "th"))
```

`cond`

operator```
(cond
predicate1 expression-to-evaluate-when-predicate1-is-true
predicate2 expression-to-evaluate-when-predicate2-is-true
...
:else expression-to-evaluate-when-all-above-are-false)
```

`cond`

example```
(cond
(< x 10) "x is smaller than 10"
(< 10 x 20) "x is between 10 and 20"
(< 20 x 30) "x is between 20 and 30"
(< 30 x 40) "x is between 30 and 40"
:else "x is bigger than 40")
```

`cond`

Write a function that can convert degrees Celcius, Fahrenheit, or Kelvin to Celcius

Here is how it should work

```
(to-celcius 32.0 :F) ;=> 0.0
(to-celcius 300 :K) ;=> 26.85
(to-celcius 22.5 :C) ;=> 22.5
(to-celcius 22.5 :gibberish) ;=> "Unknown scale: :gibberish"
```

Starting point:

```
(defn to-celcius [degrees scale]
(cond
;; ...
))
```

Formulas:

- (°F - 32) x 5/9 = °C
- °K + 273.15 = °C

Write a function that can convert degrees Celcius, Fahrenheit, or Kelvin to Celcius

```
(defn to-celcius [degrees scale]
(cond
(= scale :C) degrees
(= scale :F) (* (- degrees 32) 5/9)
(= scale :K) (- degrees 273.15)
:else (str "Unknown scale: " scale)))
```

```
(to-celcius 32.0 :F) ;=> 0.0
(to-celcius 300 :K) ;=> 26.85
(to-celcius 22.5 :C) ;=> 22.5
(to-celcius 22.5 :gibberish) ;=> "Unknown scale: :gibberish"
```

`and`

, `or`

, and `not`

`if`

statements are not limited to testing only one thing. You can test multiple conditions using boolean logic.Boolean logicrefers to combining and changing the results of predicates using`and`

,`or`

, and`not`

.

If you’ve never seen this concept in programming before, remember that it follows the common sense way you look at things normally. Is this

andthat true? Only if both are true. Is thisorthat true? Yes, if either – or both! – are. Is thisnottrue? Yes, if it’s false.

`and`

,`or`

, and`not`

work like other functions (they aren’t exactly functions, but work like them), so they are inprefix notation, like we’ve seen with arithmetic.

x | y | (`and` x y) |
(`or` x y) |
(`not` x) |
(`not` y) |
---|---|---|---|---|---|

false | false | false | false | true | true |

true | false | false | true | false | true |

true | true | true | true | false | false |

false | true | false | true | true | false |

`and`

, `or`

, and `not`

combination

`and`

,`or`

, and`not`

can be combined. This can be hard to read. Here’s an example:

```
(defn leap-year?
"Every four years, except years divisible by 100, but yes for years divisible by 400."
[year]
(and (zero? (mod year 4))
(or (zero? (mod year 400))
(not (zero? (mod year 100))))))
```

Return to the first slide, or go to the curriculum outline.