I have used clojure on some of projects in past. I have worked on Java, Ruby, C#, Nodejs projects in past and know fair bit of scala.
As I use clojure on projects, I find it very useful language. Appropriate tools are very important to do a job right.
This is how I compare Clojure to other languages.
Ruby (MRI aka CRuby)
This is one of my favorite language. Lot of other languages and their libraries are influenced by ruby world’s Rack, convention over configuration, Restful services, etc.
There is multithreading support with caveats. Only one thread which has got GIL (global interpreter lock) can run at a time. Thus making it hard to use all cores on given machine.
So if we want to process things in parallel, or async manner, we are going to do this using multiple ruby processes probably by using rescue-redis or similar. That kind of programming model where we have webapp and batch programs (using rescue-redis) can be a difficult to maintain and comprehend.
Ruby Metaprogramming has its own challenge. It’s very different than writing usual Ruby code and that make it difficult to comprehend.
Metaprogramming in Ruby is harder as it has its own special syntax and looks very different than normal ruby code.
“Some may say Ruby is a bad rip-off of Lisp or Smalltalk, and I admit that. But it is nicer to ordinary people.”
- Matz, LL2
Java is everywhere! Multithreading support and concurrent programming are strengths of the language. It can take full advantage of multiple cores on machine. Web applications can serve http endpoints as well have schedulers running Jobs using Threads with same web app. This is simpler programming model as compared to Ruby web app along with batch processing app for running jobs.
Mutable object make it really hard to reason about program. Java does not promote immutable model although it is possible to write programs that way.
Slow moving community as Java has to be backward compatible. Java is verbose.
Only functional language that became mainstream programming language. It is language of Browser!
It is used as server side programming language in Node.js. Node.js has evented architecture and non blocking IO. Again to take advantage of multiple cores multiple Node.js processes need to be used on a machine.
Evented architecture leads to callback based programming model which is harder to comprehend. Libraries like Q offers some alternative to callback using promises to simplify callback issues.
If operations are CPU-intensive, even non blocking architecture can be less performant.
Doing CPU-intensive things, we will have to follow similar batch programs model as described in Ruby section.
Excellent programming language. Support of multithreading, lambda, LINQ and generic which are available at Runtime. Closed source.
Mutable object make it really hard to reason about program. C# does not promote immutable model.
“A language that doesn’t affect the way you think about programming, is not worth knowing”
Of all programming languages I worked on, I like this one best! and yes all my Java experience is useful while using Clojure!
Clojure is Lisp! Clojure is dynamic functional programming language. Clojure runs on JVM (compiles to bytecode)
Clojure and any lisp have much simpler and lesser syntax than other non lisp languages. Parenthesis enable “code as data as code” paradigm and make macro system possible!
(some-fn arg1 arg2)
Thats the all syntax! First thing after parenthesis is function and rest of them are parameters to that function. arg1 can be other function call itself. Now try to read title of this blog post!
(some-fn (other-fn arg1) arg2)
Clojure promotes immutability. Clojure forces you to think differently as core data structure like list, vector, map and set are immutable. This is not case in languages like Scala where immutability is not forced but developers can choose to use it!
Clojure and for that matter any Lisp has almost no syntax. http://clojure.org/cheatsheet one page doc will list entire language.
Clojure has simpler concurrency support through atom, STM, agents and core async (async programming and communication which is implementation of CSP).
pmap for example is “map” higher order function which can run in parallel utilizing all available cores on machine!
Metaprogramming in Clojure is simpler and very powerful with macros. Writing macros is similar to any clojure code. Writing a code in language’s own data structure is powerful concept. Writing DSLs and new syntax just becomes as easy as writing new function.
Macros allow to add new syntax to language very easily! Adding enhanced for loop for collections in JDK took years, but in clojure you could add such syntax using macro.
Here is implementation of Ruby’s %w in clojure with macro
%w(foo bar) is a shortcut for [“foo”, “bar”] in Ruby
(defmacro %w [& params] (apply vector (map str params))) ;define %w as macro
(%w abc xyz) ;use it
Interoperable with Java. Every easy to call Java from Clojure. and also easy to call clojure from Java.
Calling Java from Clojure
Webapps in clojure are not built using frameworks, but rather using/composing many libraries. Using big frameworks is considered as non idiomatic in Clojure community.
ring — this is similar to Rack in Ruby world or Servlets in Java world.
compojure — for routing
ring-okta — for okta authentication as this app is behind TW okta. This library is just a middleware. ( middleware is higher order function). Middleware are similar to Java servlet filters.
It is very easy to call existing Java libraries from Clojure. for e.g. Okta provide java-saml-toolkit.jar which can be easily called from Clojure.
webapp is packaged as uberjar, which has embedded jetty server.
This section is intentionally left blank.