Learning Clojure Part 2: Basic syntax
Tags: clojure, tutorial
Published: 2021-01-05 08:55:11

In this next part, I will go over basic Clojure syntax and operations. We will learn all the basics we need to be productive.

## Expressions

Clojure has two kinds of structures. Literals and operations. 

Literals are your everyday data structures like numbers, strings, vectors, etc...

```clojure
1
"awesome string"
["vector" "of" "awesome" "strings"]
```

Operations are your everyday bread and water. It's how you do everything in Clojure. 
Operations take form of:
```clojure
(operator operand1 operand2 operand3 ... operandN)
```
 The important note here is that Clojure uses whitespace to separate operands.

 Example operations:
 ```clojure
 (+ 40 2)
;=> 42

(- 50 8)
;=> 42

(str "Contact" " these " "strings")
;=> "Contact these strings"
 ```

## Flow

Clojure has some basic control flow operators, that will make our life easier. Let's go over the most basic ones.

### if

With `if` you can do conditions in your code.

Structure of if expression:
```clojure
(if boolean
 then
 else)
```

So the basic example here would be something like this:
```clojure
(if true
 "Clojure seems awesome."
 "Clojure seems like a lot.")
;=> "Clojure seems awesome."
```

### do

With `do` you can chain multiple expressions into one. 
```clojure
(if true
 (do (println "Clojure seems awesome.")
 (println "And more awesome with do."))
 "Clojure seems like a lot.")
;Clojure seems awesome.
;And more awesome with do.
```

### when

With `when` you have a combination of `if` and `do`. You do not have an `else` operand tho. 
```clojure
(when true
 (println "Clojure seems awesome.")
 (println "And more awesome with when."))
;Clojure seems awesome.
;And more awesome with when.
```

### booleans and nil

There are `true` and `false` boolean values in Clojure. `nil` represents the no value. 

You can check if a value is `nil` with `nil?` expression. 

```clojure
(nil? 0)
;=> false

(nil? nil)
;=> true
```

Both `nil` and `false` stand for logical falseness, all other values are considered true. 

```clojure
(if "random string" 
 "this random string is true")
;=> "this random string is true"

(if nil
 "nil is true"
 "nil is false")
;=> "nil is false"
```

Equality operator is `=`

```clojure
(= 1 1)
;=> true

(= 1 2)
;=> false
```

Clojure also has `and` and `or` operators. Those act bit differently than in other languages. 

`or` returns the first true value or the last value. Example:
```clojure
(or false nil "this will be returned")
;=> "this will be returned"

(or (= 0 1) (= "a" "b"))
;=> false

(or nil)
;=> nil
``` 

`and` returns the first falsey value, or the last truth value (if where are no false values)
```clojure 
(and "a" "b")
;=> "b"

(and "a" nil false)
;=> nil
```

## Naming stuff

We can use `def` to name values in Clojure. 

```clojure 
(def shopping-list
 ["Vodka" "Apple jiuce" "Red Bull"])
shopping-list
;=> ["Vodka" "Apple juice" "Red Bull"]
```

Defining variables like this may seem a bit strange and hell of confusing when you would do multiple assignments into one name. This is something that should be reconsidered and done differently. 

Let's do a small exercise that would demonstrate how to write code the Clojure way.

Let's image a following piece of Java code.
```java
level = "info";
message = "message";
if (level.equals("info")) {
 message = message + " (FYI)");
} else {
 message = message + " (OMG)";
}
```
This is perfectly fine piece of code. My first instinct was do something like this:
```clojure
(def level "info")
(def message "message")
(if (= level "info")
 (def message (str message " (FYI)"))
 (def message (str message " (OMG)")))
```

If you think about it and know about the `defn` to define new operators. You can do something like this. 
```clojure
(defn error
 [message level]
 (str message
 (if (= level "info")
 " (FYI)"
 " (OMG)")))
(error "message" "info")
;=> "message (FYI)"
```

---

You can follow me on [Twitter](https://twitter.com/pavel_polivka) to get more content like this.