Complex problems require a certain simplicity in their solutions. This may sound surprising, but think about it. If both the problem and the tool for addressing it are complicated, the matrix of combinations can become unmanageable. Power isn't the same as complexity. The Clojure programming language builds on a small number of concepts to create manageable solutions to difficult problems.
Simplicity and power
Clojure's roots go back to 1958, when John McCarthy invented Lisp. Lisp, which stands for "list processing," is one of the simplest and most elegant programming languages ever devised. Clojure is a variant of Lisp designed for the modern world. These are some of the features that make it simple and powerful:
- Like Lisp, it uses a functional programming paradigm. Code can be passed around as data. This approach allows code that's focused more on what you want to accomplish than on how you do it.
- It's well-suited to concurrency, which is important in a networked world. Functional programming is a good fit for code that's triggered by events. Callbacks in object-oriented languages are more awkward.
- It uses immutable data structures. A major source of bugs in concurrent programming is variables and arrays that change at the wrong time. Clojure uses recursion instead of looping and initialized values instead of local variables, avoiding many timing bugs by design.
- It supports a rich set of data structures. They include lists, maps, vectors, and sets (generically called collections). All of them are immutable; adding a data item to one generates a new collection which is linked to the existing one for storage efficiency.
- It doesn't use inheritance. Object-oriented code can go wild with one class being an instance of another class, which is an instance of yet another class. The concept is good, but it can generate unexpected ripple effects. Clojure uses multimethods instead, based on dispatching rather than inheritance.
- It can be used as a scripted language. Programmers can invoke the read-eval-print loop from the command line, typing in code and running it immediately.
A language doesn't stand by itself; it needs to build on code libraries, or else developers have to spend time reinventing everything. Clojure runs on the Java Virtual Machine (JVM) and can invoke any Java library. It's a compiled language, turned into bytecodes before running, even when it's being used in scripting mode. That makes it fast. A Clojure program can import Java classes and call their functions.
When it does this, it loses a bit of functional purity, but some situations are best handled by object-oriented code. Java has a huge number of libraries, both in the Oracle distribution and in open-source third-party code, for frequently encountered situations. Collections are implemented as Java objects, making it easy to pass them to Java code. Well-tested code already exists to solve many problems, and it's right at hand to use in Clojure applications. This saves time and makes code reliable.
By running on the JVM, Clojure programs are inherently cross-platform. If you can run Java on a computer, you can run Clojure.
What is Clojure for?
The Clojure language isn't suitable for every job. You wouldn't use it for calculating orbits or putting pixels on a screen. However, it has a broad range of uses.
It's good for working with databases, especially NoSQL ones like MongoDB. It can handle large amounts of unstructured data. Lisp was originally conceived as an AI language, and Clojure is still better for creating code that adapts and learns.
Internet-based applications need to do useful things while waiting for data to come in. Clojure's concurrency makes it a good choice for Web and mobile applications. Its multimethods are a versatile way to handle a variety of responses.
Simple tools and clean design produce cost-effective, maintainable business solutions. Each situation has its own requirements, and we use the tools that best meet it. Contact us to learn how we can help to meet your business needs.