2 Comments

The Case for Clojure

By Paul Bostrom, Senior Software Engineer

Paul-BostromChoosing a programming language for a project is difficult. As technology progresses, new languages emerge exponentially, each one with a particular set of features; others come along that seek to improve existing features, as well as solve new problems. Clojure is a relatively new language, released in 2007 by Rich Hickey. Clojure is a Lisp-like, functional language that runs on the Java Virtual Machine. Let’s look at some of the features that make Clojure a compelling choice.

The Java Virtual Machine

The Java programming language was introduced in 1995 and provided a powerful general purpose programming language. One particular feature it provided was automatic memory management and garbage collection, so that programmers did not have to write code to manage memory like in a C or C++ program. Java also provided an execution environment called the Java Virtual Machine (JVM) to allow programs to be portable across a number of different platforms. For these and other reasons, Java has grown to become one of the most popular programming languages.

The popularity of Java has made the JVM an ideal target for the development of newer programming languages like Clojure. Just as the Java language provided features not available in C or C++, Clojure attempts to provide additional features that Java may not include, while building upon the many features that are included in the Java programming environment. Clojure also provides a number of Java interoperability features to work with the many stable Java libraries in existence. What this means in practical terms is that Clojure code can exist in a variety of forms. Perhaps you just want to write a Clojure program that is simply “glue code” to integrate several reliable Java libraries into a single application. Another option is to create a specialized library in Clojure that Java programs can utilize. Of course, Clojure provides a rich core library that allows the creation of general purpose programs that do not require any direct interaction with existing Java code.

Conciseness

Clojure code is a lot shorter than equivalent code in Java. There are a number of reasons for this, but it’s important to note that the length of the code in a software program has a direct correlation with the cost of developing and maintaining the software. Suppose a Java program is 50 lines, while the equivalent Clojure program is 20 lines, which in my experience is a typical code reduction factor between Java and Clojure. The programmer will spend less time thinking about, writing, and testing the 20-line Clojure program than the 50-line Java program, even though both programs accomplish the same task. One of the reasons Clojure programs are so much shorter is because it has dynamic types, meaning the code doesn’t require a lot of extra statements to declare the various constructs that make up the program. Other factors contributing to the conciseness are its functional programming constructs, as well as its macro system. These will be discussed in more detail below.

Functional Programming

Functional programming is a very broad topic, but one of the main concepts is the idea of first-class functions. What this means is that the programming language can define functions that are used as values throughout the program. These functions can interact with other functions by being passed along as arguments or returned as values. This differs from programming in an object-oriented program like Java, where every function (or method) must be contained within an object, which is then passed along as an argument and returned from methods contained in other objects. By allowing functional programming, Clojure lets you define exactly what your program should do without having to wrap everything in unnecessary class declarations.

Immutable, Persistent Data Structures

Clojure forces programs to use immutable data structures by default. While at first this may seem like a limitation of the language, it actually turns out to be an advantage, because it avoids the incidental complexity that is involved with mutable data structures. A data structure created in one part of a program is usually passed along to another part of the program to be used in some other computation. If that data structure can be modified during its lifecycle, it makes the program harder to reason about, and the programmer has to use more mental energy to account for the various transformations that the data might undergo. With immutable data structures, the programmer can take it for granted that the data structure will never change. Immutable data structures are even more important in multi-threaded environments, discussed in the next section.

Concurrency

Advances in technology have brought multi-core processing into all facets of computing, down to the hardware that runs mobile phones. Multiple cores allow programs to create different threads of execution to be performed simultaneously. In many cases, these threads will all want to share the same data structure. In Java there are several tools to synchronize a program across multiple threads, but these tools can be unwieldy and in some cases introduce performance penalties and are hard to diagnose bugs. Clojure provides a number of features to safely and efficiently design multi-threaded programs. One feature was mentioned above: immutable data structures. If data is immutable, there is no need to provide any coordination across threads since the underlying data cannot change. In most cases, however, it is desirable for a program to share some amount of state across its threads of execution. For these instances, Clojure provides a tool called software transactional memory (STM). This is a mechanism similar to how transactions are processed in a database and allows for safe coordination of updates to application data to prevent it from reaching an inconsistent state.

Macros

Macros are a powerful feature of Clojure and other Lisps that allow the creation of code that manipulates other code. Stated slightly differently, a macro is code that takes code as input and performs some transformation which returns an expanded version of the code as output. With macros, a program can create new syntax rules and language constructs to make a specific task easier to implement. Macros can even be used to create wholly new languages, known as Domain Specific Languages, which might cater to a particular class of programming tasks.

Hopefully the information in this article has revealed a number of advantages to using Clojure in your next software project. In some cases, just the ability to concisely construct a program is enough of an advantage to warrant choosing Clojure. With additional requirements for concurrent execution, Clojure becomes an even more compelling choice.


Leave a comment

The Tale of the Process Challenged Pig

by Phillip Smith, Vice President of Operations and Services

Phil Smith Bridge360Once upon a time there was a wolf and three pigs.  One pig acted in a cost conscious manner.  One acted with urgency.  The other one… well, he stayed in business long enough to tell the story.  In IT, we need all three attributes:  cost consciousness, motivation, and quality focus.  Yes, the quality conscious pig who built with reliable design and materials is going to be the first one that I’ll select to be on my project team.  This individual not only cared about the end result, but he (not being gender biased here; I looked it up and the three pigs were males, sorry ladies) cared about the process.  He thought about how to measure success (security was considered in the requirements) and about sustainability (I understand a wood stove and a chimney were included).  The windows had curtains and shutters which increased usability, and the foundation was solid with an open floor plan in case of further expansion.

The third pig used a process to get to his end result.  He did not react; he planned.  He followed what he had learned in the past and put his best skills and resources to work.

In real life, I don’t get to pre-wire all of the members of a project team, and most of them, myself included, are not wired like that last pig.  In fact, most of us are wired with action (get it done, move on to the next task) and with a tendency to think about getting there with low cost, which is always noble and usually rewarded.  In fact, most of us have to stop and remind ourselves of the things we were taught that may not be inherent in our genes—namely, to plan and deliberately execute, rather than to simply execute.

Therefore, project teams, by nature, are made up of people with a mixture of tendencies, and many of them will not be process oriented.  It is important that teams be intentionally staffed and supported by people who value process and are capable of influencing their other team members.

When we drive our cars, we all follow a basic set of rules based on lanes, signals, and safety.  We all understand and accept these rules, and follow along with them without much discussion.  Yes, similar rules exist in the world of software development.

Such as:

  • Requirements should be documented and validated
  • Testing should be planned
  • Work products should be reviewed
  • Team members should be trained

I could go on for a while with this list.  And, very few in the software industry would argue with these basic rules.  Yet some of the most talented engineers are comfortable moving straight from a conversation with the client to writing code.

I want these talented engineers on the team.  I also want to balance their action oriented initiative with some process so that the end result is similar to the brick house.  If the three pigs had pooled their talents, they would have all been better off.

One parting shot… don’t load your whole team with process people unless you are creating a PMO.  They are certainly invaluable, but if you put them all together they will build a better process, not a brick house.