(defn square [x]
(* x x))

(deftest square-test
(is (= 0 (square 0)))
(is (= 1 (square -1)))
(is (= 1 (square 1))))

I thought that you would have to be mad to use it. However, since functional programming has become more and more popular, I decided to give it a try and changed my mind (or became mad). In this post, I will try to share with you some of Clojure's (Lisp for the JVM) beauty.

Note: I'm still learning the language, so I might be oversimplifying things. If you're a seasoned Clojure programmer, you risk a heart attack reading this. :)

Hello World!

(println "Hello world!")

This is a "Hello World" program in Clojure (using REPL). The syntax is pretty basic:

• Everything goes in parens:
(...)

• Function name goes first:
(function-name ...)

• Then arguments, if there are any:
(function-name arguments)

The square function, defined in the first listing, would be called like this:

(square 2)

As you can see, there aren't more parens in Clojure than there are in Java, you just move the paren to the left!

Java:                 Clojure
square(2);            (square 2)
square(square(2));    (square (square 2))

Math Operations

Math operations like + or * also go first in the expression. Actually, these symbols represent Clojure functions. It might take a while to get used to it.

(+ 2 2)
(- 2 2)
(* 2 2)
(/ 2 2)

Actually, this notation isn't any harder than the "normal" one — just remember that operation goes first.

Java:             Clojure:
2 + 2             (+ 2 2)
square(2);        (square 2)

Defining a Function

To define a function we use the defn macro.

1. We call defn:
(defn ...)

2. Then we declare function's name:
(defn function-name ...)

3. Then we declare the parameters in square brackets:
(defn function-name [param] ...)

4. Finally we put the body:
(defn function-name [param1 param2]
expression1
expression2)

Last expression in the body acts as a return statement.

Java:                             Clojure:
int f() { return 1; }             (defn f [] 1)
int g(int i) { return i; }        (defn g [i] i)

Now the square function should be easy to understand. We take an argument x and return (* x x). Piece of cake!

Conditions

There is an if construct (special form) in Clojure, but it works a bit differently than the Java keyword. It works the same as Java's ternary operator — it returns one of two values based on a condition. Here's the usage:

1. We call if:
(if ...)

2. Then we enter a condition:
(if condition ...)

3. Then goes the value to be returned when the condition is true:
(if condition then)

4. Lastly, we can put a value to be returned when the condition is false:
(if condition then else)

An example might help a lot in understanding:

(if (> x 0) "positive" "zero or negative")
(if (< x 0) "negative" "zero or positive")

If we want to chain conditions, like if-else in Java, we should use the cond macro. It's syntax looks like this:

1. Macro call:
(cond ...)

2. List of conditions with associated expressions:
(cond
(< x 0) "negative"
(> x 0) "positive")

3. Optional "else" expression:
(cond
(< x 0) "negative"
(> x 0) "positive"
:else "zero")

Solving a Real Problem

Enough learning for today. It's time to save the world by tackling the very famous "Fizz buzz" problem.

We'll start by defining a function taking one argument and returning it:

(defn fizzbuzz [x] x)

This solves problems for non-divisible numbers. Let's make a "fizz":

(defn fizzbuzz [x]
(if (= x 3) "fizz" x))

That's a naive solution, because it doesn't work for 6, 9 etc., but we'll solve that later. Let's add a buzz:

(defn fizzbuzz [x]
(cond
(= x 3) "fizz"
(= x 5) "buzz"
:else x))

"Buzz" is there. With cond in place, adding "fizzbuzz" is trivial:

(defn fizzbuzz [x]
(cond
(= x 3) "fizz"
(= x 5) "buzz"
(= x 15) "fizzbuzz"
:else x))

Perfect. It's high time to make the "fizz", "buzz", and "fizzbuzz" work for other numbers than 3, 5, and 15. We'll use the mod function for this:

(defn fizzbuzz [x]
(cond
(= 0 (mod x 15)) "fizzbuzz"
(= 0 (mod x 3)) "fizz"
(= 0 (mod x 5)) "buzz"
:else x))

Notice, we had to move the "fizzbuzz" case up, because of the "fizz" and "buzz" conditions. That's it, world saved!

Conclusion

Despite the first impression, Clojure is a pretty simple language. Main constructs like functions, math operations or conditions are pretty similar to other languages. What's important, the language is capable of solving super-complicated problems like "Fizz buzz". I hope you had some fun!