Why Clojure? Four Tech Reasons

DZone 's Guide to

Why Clojure? Four Tech Reasons

We take a look at why you'd want to use Clojure for your projects from a developer's point of view.

· Web Dev Zone ·
Free Resource

Clojure isn’t a mainstream programming language. But the FreshCode team regularly completes projects with this powerful and convenient solution. That’s why I want to describe technical reasons in which Clojure development matters.

Original published at freshcodeit.com

Why Clojure?

What is the final goal of creating any programming language? From my point of view, it aims to enable writing clear and effective code. Rich Hickey, the author of Clojure, wanted to make written programs simple. This helps to speed up the software development process, as well as reduce the time needed for code understanding, changing, and support.

“Simplicity is a prerequisite for reliability” - Edsgar W. Dijkstra

Clojure's syntax can be a challenge for beginners. At the same time, it’s easy and convenient for learning and coding. After getting used to this language, you will see the technical benefits, which are especially important for enterprise projects.

All Clojure advantages are based on four principles. Let’s see how they are implemented in the language.

1. Homoiconicity

Clojure is related to the prominent and elegant Lisp family. One of its main properties is homoiconicity, which causes lively debate among software developers worldwide. According to Wikipedia:

A language is homoiconic if a program written in it can be manipulated as data using the language. Thus the program’s internal representation can be inferred just by reading the program itself.”

Imagine a Lisp program, which is presented as a normal Lisp list. Meanwhile, you can manipulate it using other Lisp code. So, Clojure developers can access and transform code into data. This Lisp peculiarity shows the concept of “code as data.”

This feature is conceptually possible because of the minimalist and utterly consistent Clojure syntax. The whole program code is represented via S-expressions (tree-like structures). This is the of same type of code representatoin as that supported by Clojure Core. So, code can be easily transformed into data through macros.

The strong macro system gives an opportunity to create code that generates other code. It enables software developers to write extensions without waiting for the programming language designers to implement it. The latter is also relevant for writing you own Domain-Specific Languages (DSLs) with the help of macros. They are responsible for the “translation” from your language to Clojure.

The benefits of well-designed DSLs are obvious. Clojure’s macro system gives you excellent opportunities for using them.

Writing the internal DSL with these macros leads to a new level of code refactoring. It also expands the language itself with modern elements. They are useful for the implementation of business goals in the context of each specific project.

The core.async macro in Clojure is one of the best examples of this principle benefit. core.async brings the power of CSP-style concurrency to Clojure. Thanks to the macro, it was created as a library without interrupting the Clojure language.

Compojure is another popular Clojure library that is based on the homoiconicity principle. Look at the example:

(defroutes static-routes
    (GET ["/static/:location", :location #"([/a-zA-Z0-9_.-]+)$"]  [location] {:status 200 :body "OK"}))

Here you can see the macro “GET”, which extends the language syntax. It provides a convenient interface for describing a series of “GET” endpoints. Their URL starts with /static/. The “location” parameter is also reverse here and validated with the help of regular expressions.

Look how we can transform this code:

 #clout.core.CompiledRoute{:source "/static/:location", :re
#"/static/(([/a-zA-Z0-9_.-]+)$)", :keys [:location], :absolute? false}
(fn [autogenerated-parameter]
 (compojure.core/let-request [[location] autogenerated-parameter] {:status 200, :body "OK"})))

An anonymous function-processor is created here. It is transmitted to the special function make-route, which puts the function-processor into the supportive middleware.

This seems complex, but, in reality, this Clojure abstraction provides a nice coding experience and helps to make things referentially transparent. The macro above is needed for hiding the realization details from the developer. That is, of course, until he/she doesn’t need them.

2. Functional Approach

What causes complexity and problems in computer programs? Side effects are among the main factors of our challenges. You can’t fully avoid them. But you can localize the spillovers and the programming language should help you.

As a functional language, Clojure encourages you to write pure functions. The results of such functions depend only on the input parameters. So, it doesn’t matter how many times you start the function. The result is always the same. This simplifies testing because you don’t have to try various queues and find the right state of inputs.

Pure functions are also handy for analyzing and refactoring. They are extremely simple, even if they do a great job.

Clojure's beauty lies in how the language perfectly joins individual elements into a coherent whole.

Clojure, like JavaScript, operates using functions as values. So, they can be transmitted as parameters and returned from other functions. This provides flexibility for a developer because he/she can delay or customize an on-the-fly logic realization. Moreover, the functional approach enables making the processors middleware by default. So, you can customize them for different business goals, which range from logging to conditional email sending.

3. Immutable Data Structures

Clojure has features of an object-oriented language. So, it initially includes a set of immutable (unchangeable) structures and methods for working with them.

They look like common JavaScript arrays and Hash Maps. But any operation can’t change their values. Instead of changing, it creates an absolutely new structure with updated data.

The immutability is handy when writing multithreaded applications because it negates a whole class of bugs related to synchronization of changing variables between threads. So, you can build entire information models using the few immutable data structures included in Clojure. The predictable code is easier to write and easier to test, which helps to develop a product quickly.

For example, look at the FreshCode use case. The development of e-commerce platform that supports more than one million users took just 4 months. It proves that Clojure allows programmers to focus on engineering efforts instead of extra details.

4. A Multipurpose Solution

Clojure is a good choice for a wide variety of projects. You can use it from social networking industry to Big Data solutions. Initially, Clojure language was targeted for working with JVM. So, the most popular modern Clojure implementation uses the Java Virtual Machine. This enables simple interaction with Java libraries, creation of Java objects and using the Maven repository. Java platform’s maturity and the huge ecosystem provide many benefits for Clojure developers.

An interesting fact is that although JVM primarily runs Java, about 3% of JVM users are programming in Clojure. It’s a remarkable fact, which shows the great potential of functional programming and Clojure itself.

Graph of JVM Users; Original published at freshcodeit.com

Moreover, ClojureScript is actively developing. This is another Clojure implementation, which includes compilation to JavaScript.

Due to the same syntax, you can write front-end in ClojureScript and backend in Clojure (or ClojureScript in the case of Node.js applications). What is more, sometimes the same code overlaps in the front-end and backend. The Clojure compiler allows you to put this code in *.cljc files and use it simultaneously on both sides.

Principles of Clojure; Original published at freshcodeit.com

More Reasons to Fall in Love With Clojure

Clojure has several other strengths that make it a good solution for your product. Let’s take a look at them.

  • Performance: Clojure provides you performance that fits for working with a lot of data (it’s close to Java). On the other hand, you don’t have to pay a price in productivity or expressiveness.

  • Community: Clojure has an enthusiastic, vibrant community, which encourages innovation and fresh ideas. By the way, about 27% of Clojure users are actively helping newbies.

  • Usability: Clojure is a practical and pragmatic language. It helps to organize a fast and efficient software development process. So, I can recommend it for rapid prototyping and lean startups.

  • Polymorphism: It’s an important feature for building extensible and flexible systems. Clojure is able to support multiple taxonomies and dispatches via static, dynamic, or external properties, metadata, etс. It’s the best implementation of the polymorphism concept I’ve ever seen.

  • Reliability: Adopted by Citibank, Simple (formerly BankSimple), Pico Quantitative Trading, Amazon, Netflix, Groupon, and many other great companies, Clojure already proved its reliability and stability.

  • Innovativeness: Clojure combines Lisp’s power with many modern features, such as software transactional memory (STM), interactive programming through a read-eval-print loop (REPL), simple Java API calls, etc.

My articles will cover other aspects of cost-efficient software development. So, stay in touch and enjoy the meaningful content by the FreshCode team! You can also share your experience in using different programming languages and tools. I’m curious about your thoughts on writing code that matters.

By the way, you can read the previous post to find out the best open source technologies for coding in Clojure.

clojure ,clojure for beginners ,immutable data ,java ecosystem ,jvm ,web dev

Published at DZone with permission of Vladimir Pavlyuk . See the original article here.

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}