It’s not a secret that almost all of my professional career was related to C# and .Net technologies.
After some years I got fed up with how certain things worked in this “area” (maybe I will write about it someday) and
decided to scratch all that and become junior again.
You could say that what I was about to do next, was decided for me ;)
After some unexpected weave of events, I’ve started working as Clojure developer.
That was a ride!
I’ve jumped from .net object-oriented language to fully functional dialect of LISP-based on JVM.
I don’t know if it could be any more different.
But I got what I’ve wished for and had a great time working with Clojure till today.
It’s over 3 months now, so I decided to do quick ‘review’ and point out 3 things that I like and
3 things that I dislike about that language.
Bear in mind I’m new to this, so maybe I didn’t catch all the nuances yet + that’s my personal view on the topic.
Let’s start with…
Good things
1. Macros
Or I would rather say the famous “Code is data”.
It’s hard to describe all of this in a few words, but in Clojure (and I think in all LISP dialects) functions or operators are the same structures as your data.
That means there is no difference in a list with numbers or a list containing function name and it’s arguments.
Given above, macros let us extend the language by operating on those lists. We can read some data, manipulate it and emit it in a different form for Clojure compiler.
In Clojure, we call functions in the following format: (fn_name arg1 arg2 arg3)
.
That means simple addiction would look like this: (+ 1 1)
With macros, we can extend our language with new infix
operation like this:
(defmacro infix
[infixed]
(list (second infixed) (first infixed) (last infixed)))
and the use it as:
(infix (1 + 1))
The great thing about macros is that it’s not quirky low level stuff, but rather a first class citizen. Quite a lot of clojure functions are macros that wrap some fundamental operations (like when
is just a macro that uses if
).
2. Java
Clojure is implemented on JVM machine.
That’s quite a big advantage. First of all, it’s a very widely used piece of software that was thoroughly tested in various scenarios.
There are good tools and knowledge about how to tune JVM or look for errors.
With JVM one can also use Java code in Clojure, built in interop is quite powerful.
That means every library created for Java (and we all know, there is almost anything already written for Java) can be used in Clojure too.
That single fact could be huge time/cost saver in a project.
3. REPL
REPL aka Read-Eval-Print-Loop is a programming environment where a developer can interact with a running program by evaluating expressions one by one.
It was something new to me, to be honest. Don’t get me wrong, I was using languages that had REPL before (hello Ruby ;) but I’ve never had this ‘click’ moment to actually leverage it as a tool for writing code.
With REPL and few plugins you can write and execute code just from your text editor. No need to recompile or restart the project.
That’s quite a convinient feature that speeds up development as you don’t need to wait for JVM to boot up ;)
That leads us to:
Bad things
1. Java
Interop and access to a vast number of Java libraries is one thing.
But slow startup and some memory problems are in the same package. You just need to live with it.
2. Clojure is huge!
One could say that Lisp has no syntax. That’s probably true. Few parentheses and simple rules and you’re good to go.
That + good standard library makes for elegant and concise code.
But!
To master all of this you need a lot of time and patience.
There is more than one way to do things and a lot depends on how long you work with Clojure.
That makes your first code reviews in Clojure a bit daunting, as I’m more than sure that someone will point out that those three expressions you have there could be replaced with some one fancy keyword.
That also makes Clojure code a bit hard to read at first as you generally need to look at the docs to see what given function does (and to add to that, not all function names in STL are clearly named).
3. Errors
Last on my list for today is errors and exceptions. They are a bit cryptic at first and if you write your code in nested expressions, given line number won’t help you that much.
I believe it’s mainly due to JVM base and the fact that all Clojure code needs to be somehow reflected in Java related types in the end.
Good news, it’s getting easier with time, you start to write cleaner code and get some experience with deciphering the error messages.
That’s it folks, my 3 pros and 3 cons for Clojure at the moment.
Even if I believe it’s not perfect, I recommend at least try to do something with it. It’s a very elegant language with lots of power coming from the JVM base.
If you’ve tried it already, what are your most/least favorite features of CLJ ?