Escrito por Rodrigo Tejada,

7 minutos de leitura

Clojure first impressions

This post will talk about clojure and some problems encountered in my journey to learn about it.

Compartilhe este post:

I have spent the last weeks learning about clojure and it was a great challenge having a strong object oriented background without being so familiar with functional and dynamic languages. This post will talk about some problems encountered in this journey.

 

The syntax

 

First thing you may notice is the lisp based syntax, parenthesis everywhere. The code fastly starts to look like an onion with layers of funcionts calls inside one another and the execution order is a bit tricky to understand once it is in inside out order. Fortunately there is a little trick to solve this problem the famous “->>” known as the “thread-las macro”.

It basically inverts the execution order of your code, instead of inside out execution you can concatenate functions to be executed from top to the bottom.

Normal clojure function:

(defn factorial-seq [n]
(next(range(inc n))))

Thread last macro:

(defn factorial-seq [n]
( ->> (inc n)
(range)
(next)))

The main benefit is that the execution order follows the reading flow and you do not need to invert the reading logic.

Another common doubt is to understand when to use the parenthesis or not, the answer is simple parenthesis will only be necessary when you are calling a function.

Function call:

(defn print-hello [] (println “Hello World”))

Simple return

(defn get-hello [] “Hello World”)

The first function “print-hello” has the body wrapped in parenthesis because it calls the function “println”, in the other hand the function “get-hello” does not need this because it just returns a string.

Another thing that is worth mentioning is that functions declarations order do have a great importance, you can only call functions declared above not bellow. So you need to be a little bit more carefull but its easier to indetify the dependencies, they will usually be above the given functions.

 

Immutability

Clojure favors Immutability, so trying to do a simple POC with a mutable data structure showed to be more complex then usual.

Atom is a wrapper that provide a way to manage shared, synchronous and independent state from variables. Changes to atoms are always free of race conditions and you can use “swap!” to do thoses changes.

;;defines an empty list
(def a ‘())

;;creates a new list with the element 1 not changing “a”
(conj a 1)

;;creates an atom empty list
(def b (atom ‘()))

;;mutates the atom b adding the new value “1”
(swap! b conj 1)

 

Documentation

Clojure official documentation and clojuredocs are the best way to go, there are plenty examples and helps to understand the behavior of each function. It is very complete and can save you from a lot of problems. The thing is that beeing not so famous language as java for example we do not have thousands of posts and stackoverflow questions to help. Facing common daily problems can be a bit tricky, but you should be able to always come to a solution since there are big companies using it on production scale applications such as Nubank, Netflix and Linkedin.

 

Type safety

Coming from an object oriented language which embraces always declaring types and arriving into clojure seems a bit odd when you do not need to declare function parameters types nor return type. This could get into a mess when you are in bigger chain of functions and need to keep track of types returned by each operation.

There is an option to use “type hints” to specify which type can be used, but as the idea is to be a dynamic language that is not a common practice. That brings up some doubts about the impact of that in large refactors and how they can be tricky without having IDE support to indetify those changes.

 

Conclusion

Clojure is a totally different paradigm, you cannot try to write java code in clojure, the goal is to embrace the functional style. Doing that you get the main benefits from it as it favors immutability. Another point is that in java a lot of code is needed to create simple functionalities and clojure on the other hand is more concise. It also runs on JVM and all the java ecosystem is available such as libraries and custom integrations.

Therefore i strongly recommend to give it a try, it will force you to change the way you see functions and think about new ways of problem solving.

 

Links:
https://clojure.org/reference/reader

https://clojuredocs.org/

Compartilhe este post: