# I am a horse in the land of booleans

Any program is only as good as it is useful. Linus Torvalds

## Fork this

https://github.com/iloveponies/i-am-a-horse-in-the-land-of-booleans

Here are the instructions if you need them. Be sure to fork the repository behind the link above.

## If then else

Any non-trivial program needs conditionals. Clojure’s `if`

looks like the following:

```
(if (my-father? darth-vader) ; Conditional
(lose-hand me) ; If true
(gain-hat me)) ; If false
```

`if`

(usually) takes three parameters: the conditional clause, the *then* body and the *else* body. If the first parameter - the conditional clause - is true, the *then* body is evaluated. Otherwise, the *else* body is evaluated.

Clojure has two boolean values: `true`

and `false`

. However, all values can be used in a boolean context like `if`

. Everything except `nil`

and `false`

acts as `true`

. For example, all of the following are valid Clojure:

```
(if "foo" "truthy" "falsey") ;=> "truthy"
(if 0 "truthy" "falsey") ;=> "truthy"
(if [] "truthy" "falsey") ;=> "truthy"
(if false "truthy" "falsey") ;=> "falsey"
(if nil "truthy" "falsey") ;=> "falsey"
```

`nil`

is Clojure’s `null`

value. We’ll talk about it later.

To make it easier to talk about values in boolean context, we define the following terminology:

If a value is considered true in boolean context, we call it

*truthy*.If a value is considered false, we call it

*falsey*.

Any value can be turned into `true`

or `false`

with the `boolean`

function:

```
(boolean "foo") ;=> true
(boolean nil) ;=> false
```

### Exercise 1

Implement `(boolean x)`

, which works like the built-in `boolean`

function: for `nil`

and `false`

, it returns `false`

, and for all other values it returns `true`

. You can use `if`

in its implementation, but not the build-in `boolean`

.

```
(boolean "foo") ;=> true
(boolean nil) ;=> false
(boolean (+ 2 3)) ;=> true
(boolean true) ;=> true
(boolean false) ;=> false
```

## Comparing values

Values can be compared for equality with `=`

:

```
(= "foo" "foo") ;=> true
(= "foo" "bar") ;=> false
```

Numerical values should be compared with `==`

:

```
(== 42 42) ;=> true
(== 5.0 5) ;=> true
(= 5.0 5) ;=> false !
```

Note the difference between `=`

and `==`

: `==`

disregards the actual type of the numeric value, whereas `=`

requires that the numbers are of the same type.

Less-than, greater-than and other such comparisons can be done with the regular `<`

, `>`

, `<=`

and `>=`

operators:

```
(< 1 2) ;=> true
(> 1 2) ;=> false
(<= 52 2) ;=> false
```

## Comparing many values

All the comparison functions above take an arbitrary amount of arguments. For an example, to compare if three variables are equal, one can give them to `=`

:

`(= x y z) ;=> true if and only if x = y = z`

The other comparison operators work similarly. You can easily check if given variables are in ascending order:

`(< x y z q) ;=> true if and only if x < y < z < q`

### Exercise 2

Write the function `(teen? age)`

, which returns truthy if `age`

is at least 13 and at most 19. Use only one comparison operator and give it three arguments.

```
(teen? 12) ;=> false
(teen? 13) ;=> true
(teen? 15) ;=> true
(teen? 19) ;=> true
(teen? 20) ;=> false
(teen? 27) ;=> false
```

## Everything has a value

In functional programming, and specifically in Clojure, everything is an expression. This is a way of saying that everything has a usable value. Concretely, `if`

has a return value; the value is the value of the evaluated body (either the *then* or the *else* body).

As an example, let’s define the function `(sign x)`

, which returns the string `"-"`

if `x`

is negative and otherwise `"+"`

. The function looks like the following:

```
(defn sign [x]
(if (< x 0)
"-"
"+"))
```

The function definition has one expression, which is an `if`

expression. The value of the function is the value of the `if`

expression, because it is the last expression in the function body. The value of the `if`

expression is either `"-"`

or `"+"`

, depending on the value of the parameter `x`

.

You can paste the function into the REPL and try calling it with various values of `x`

:

```
(sign 2) ;=> "+"
(sign -2) ;=> "-"
(sign 0) ;=> "+"
```

There is no need for a `return`

clause – there is no such keyword in Clojure – because the return value of a function is always the value of the last expression in the body of the function.

### Watch out!

`if`

does *not* have a return value in a language like Java. In other words, it is not an expression, but a statement. Because everything in Clojure is an expression, there is no equivalent construct to Java’s `if`

in it.

For illustration, you could use Java’s `if`

to implement `sign`

:

```
String sign(int x) {
if (x < 0)
return "-";
else
return "+";
}
```

Note that you need to use the `return`

keyword to indicate when to return from the method. Compare this to Clojure, where the last expression’s value will be the function’s return value. Because Java’s `if`

does not return a value, you can not say:

`return if (x < 0) "-" else "+"; // Illegal Java!`

## Conditional evaluation

In any case, *only* the appropriate expression is evaluated. So the following is not an error:

```
(if true
42
(/ 1 0))
```

If evaluated, `(/ 1 0)`

would throw an `ArithmeticException`

due to the division by zero. However, the `if`

expression does not evaluate the division at all, because the conditional clause is true and only the *then* body, `42`

, is evaluated.

### Exercise 3

Write the function `(abs n)`

, which returns the absolute value of `n`

, i.e. if \(n < 0\), the value of `(abs n)`

is \(- n\), and otherwise \(n\).

```
(abs -2) ;=> 2
(abs 42) ;=> 42
```

### Exercise 4

Write the function `(divides? divisor n)`

, which returns `true`

if `divisor`

divides `n`

and `false`

otherwise.

`(mod num div)`

returns `0`

if `div`

divides `num`

exactly:

```
(mod 10 5) ;=> 0
(mod 3 2) ;=> 1
```

```
(divides? 2 4) ;=> true
(divides? 4 2) ;=> false
(divides? 5 10) ;=> true
(divides? 2 5) ;=> false
```

## Conditioning

When checking for multiple conditions, you can use multiple `if`

clauses:

```
(if condition1
true1
(if condition2
true2
(if condition3
true3
...)))
```

This is similar to `if`

/`else if`

in languages like Java. However, the nested `if`

clauses are awkward. We can rewrite the nested `if`

clauses with the `cond`

builtin.

The general form of `cond`

is:

```
(cond
condition1 true1
condition2 true2
condition3 true3
...)
```

Like with `if`

, you can have an else branch in the end. The condition for the else branch is `:else`

.

```
(defn super-sign [number]
(cond
(neg? number) "negative"
(pos? number) "positive"
:else "zero"))
(super-sign 13) ;=> "positive"
(super-sign 0) ;=> "zero"
(super-sign -5) ;=> "negative"
```

### Exercise 5

Write the function `(fizzbuzz n)`

that returns

`"fizz"`

when`n`

is divisible by 3,`"buzz"`

when`n`

is divisible by 5,`"gotcha!"`

when`n`

is divisible by 15, and- the empty string
`""`

otherwise.

Use the `divides?`

function from the previous exercise.

```
(fizzbuzz 2) ;=> ""
(fizzbuzz 45) ;=> "gotcha!"
(fizzbuzz 48) ;=> "fizz"
(fizzbuzz 70) ;=> "buzz"
```

### Exercise 6

Write a function `(generic-doublificate x)`

that takes one argument and

- doubles it if it is a number,
- returns nil if it is an empty collection,
- if it is a list or a vector, returns two times the length of it
- returns true otherwise.

You can use the following functions:

`(number? n)`

returns`true`

if`n`

is a number.`(empty? coll)`

returns`true`

if`coll`

is empty.`(list? coll)`

and`(vector? coll)`

test if`coll`

is a list or a vector.`(count coll)`

returns the length of a list or a vector.

```
(generic-doublificate 1) ;=> 2
(generic-doublificate [1 2]) ;=> 4
(generic-doublificate '(65 21)) ;=> 4
(generic-doublificate {}) ;=> nil
(generic-doublificate []) ;=> nil
(generic-doublificate {:a 1}) ;=> true
```

## Boolean Functions

The common boolean functions in Clojure are `and`

, `or`

and `not`

. These roughly match the `&&`

, `||`

and `!`

operators of languages like Java.

```
(and true true) ;=> true
(and true false) ;=> false
(or true false) ;=> true
(or false false) ;=> false
(not true) ;=> false
(not false) ;=> true
```

`and`

and `or`

take an arbitrary amount of arguments:

```
(and true) ;=> true
(and true true true) ;=> true
(and true true true true false) ;=> false
(and) ;=> true
(or false false false false true) ;=> true
(or false false false) ;=> false
(or) ;=> nil
```

In addition to booleans, `and`

, `or`

and `not`

accept non-boolean values as arguments as well. (Remember that `false`

and `nil`

are falsey and everything else is truthy.)

By the way, if you have a lot of long parameters to `and`

, or any function for that matter, indent them like this:

```
(and very-long-boolean-holding-parameter
another-one-that-is-a-friend-of-the-previous
the-third-guy)
```

`and`

returns truthy if all of its arguments are truthy:

```
(and "foo" "bar") ;=> "bar"
(and "foo" false) ;=> false
(and 10 nil) ;=> nil
```

`or`

returns truthy if any of its arguments is truthy:

```
(or "foo" false) ;=> "foo"
(or 42 true) ;=> 42
```

`not`

returns `true`

if its argument is falsey and `false`

if its argument is truthy:

```
(not "foo") ;=> false
(not nil) ;=> true
(not []) ;=> false
```

This behaviour might look surprising, but it is consistent. What’s happening is that if all the arguments to `and`

are truthy, it returns the value of the last argument. Otherwise, it returns the value of the first falsey argument. Conversely, `or`

returns either the first truthy value or the last falsey value.

While it might seem odd that boolean functions return non-boolean values, remember that all values in Clojure in fact act as boolean values. This behaviour is useful in many situations. For an example, it allows you to provide default values for variables when taking input:

`(def server-port (or user-input 80))`

Note that this can only be used in situations where the input may not take the values `false`

or `nil`

.

### Exercise 7

Write the function `(not-teen? age)`

, which returns `true`

when teen? returns `false`

and `false`

otherwise.

```
(not-teen? 13) ;=> false
(not-teen? 25) ;=> true
(not-teen? 12) ;=> true
(not-teen? 19) ;=> false
(not-teen? 20) ;=> true
```

### Exercise 8

Write the function `(leap-year? year)`

, which returns `true`

if `year`

is a leap year, otherwise `false`

. A year is a leap year if it is divisible by 4, except if it is divisible by 100, in which case it still is a leap year if it is divisible by 400.

See Wikipedia for a simple pseudocode solution.

```
(leap-year? 100) ;=> false
(leap-year? 200) ;=> false
(leap-year? 400) ;=> true
(leap-year? 12) ;=> true
(leap-year? 20) ;=> true
(leap-year? 15) ;=> false
```