Clojure is modern dialect of programming language Lisp. It is a universal language, which supports functional programming. It focuses mainly on simplifying the multi-threaded app development. For its run uses runtime environment JVM or CLR. It sticks to the philosophy of a code, which acts as data and implements sophisticated Lisp macrosystem.
Rich Hickey decided to develop Clojure because he needed modern Lisp, which would cooperate with the expanded Java platform and which would be designed for multi-threaded app development.
Clojure uses concept of identities for the solution of concurrency control. Those we can imagine as series at the time of invariant states. Regarding to the fact, that these states have immutable values, it is possible to operate random number of threads in parallel above them and the concurrency control then rests in managing transitions from one state to another. For that purpose, Clojure provides four changeable reference types, from which each has clear semantics for the definition of transitions among individual states.
As Lisp, the Clojure syntax is built on s-expressions, which are firstly taken apart on a level of data structures and then compiled. Clojure simultaneously supports literals for structures, as e. g. lists, maps, sets or fields. Those are then transmitted to the compiler as they are. Clojure is not designed so it would be compatible with other Lisp dialects.
Macros
Macros play an important role in Clojure. It is a construction, which are in arguments transmitted by s-expressions, from which is then random code built. The code is then executed. Maker system is in Clojure similar to the concept of the Common Lisp code.
Typical features of Clojure
The development is dynamical with the use of REPL
Functions are first-class objects, which emphasize on recursion instead of loops, which create side effects.
Sequences are lazy evaluated.
There is a rich set of invariant data structures available.
It is strongly integrated with Java. The language code is compiled to JVM bytecode. Thanks to that, it can be easily put to the common JVM environment and app servers. The language simultaneously provides macros, which simplify the existing Java API usage; its structures directly implement standard Java interface, by which is possible to execute the code written in Clojure directly from Java.
It allows concurrent programming with the use of software transaction memory, agent system and dynamical type system.
Dynamical execution of method allows multi-methods and their concrete implementations are selected based on the type of transmitted parameters.
The advantages of using Clojure
Simplicity and elegance. Clojure is simple and elegant language, where most of the functionalities need less of the code than in other languages, which increases the productivity and decreases the risk of errors.
Safety. Safety is increased thanks to immutability, the high level of loops and manipulation with data, construction of competition and mantras of functional programming, which ensures cleanliness.
The efficiency. The efficiency is on the same level as Java and the language structure supports in the writing of an efficient code by enabling wide scale of highly optimized data structures. It also has the support of fast processing in more threads.
Disadvantages of working with Clojure
Memory. It is not very effective when working with memory, by which increases hardware costs, because it requires servers with significant memory.
The difficulty of learning. In the initial phase, it is very difficult to orientate in the language, what can scare off many of developers.
Responsivity. Clojure cannot be used for services in real time.
Difficult cooperation among developers. For bigger teams can be difficult to work on code together.
Less readable error messages.
It is not suitable for highly efficient low-level code. For these cases, it is more suitable to choose C, C++, Rust or Assembly.