The Convenience of ClojureScript for Complex Applications

Leave a comment

by Paul Bostrom, Senior Software Engineer

Paul-BostromIn my last blog post, The Case for Clojure, I discussed the advantages of using the Clojure programming language for writing applications on the Java Virtual Machine (JVM). Clojure’s success on the JVM led the language designers to compile the language for JavaScript engines, resulting in ClojureScript. Practically every device that can connect to the Internet has a web browser containing a JavaScript engine, making it an appealing target for developing applications.

Unfortunately, the JavaScript language contains flaws that make it difficult for developers to manage the complexity inherent in large applications. The widespread adoption of JavaScript presents a barrier to fixing these flaws without breaking existing applications. The JavaScript community has constructed various conventions in attempt to refine JavaScript’s faults, however these conventions have an ad-hoc nature and are not consistently applied. ClojureScript provides developers with an entirely new language and set of semantics that can be executed on any existing JavaScript engine. ClojureScript avoids JavaScript’s shortcomings while providing a number of new programming paradigms not currently available in the JavaScript ecosystem.

A Comparison of Clojure and ClojureScript

Clojure and ClojureScript are essentially identical languages, although they differ in the way that they deal with their respective execution environments, the JVM and the JavaScript engine. ClojureScript has the ability to interoperate with all of the interfaces that JavaScript uses, like the browser window, the document object model (DOM), and HTML5 APIs. ClojureScript uses the same immutable data structures as Clojure on the JVM. In a multi-threaded environment like the JVM, immutable data structures provide a nice alternative to the complex locking code used to preserve the integrity of data structures across multiple threads. Almost all JavaScript engines are single threaded, and only one particular section of code can run at any time. However, JavaScript engines are designed to handle asynchronous events that might be generated by a user interaction like a mouse click. It is hard to predict in what order related sections of code will run when developing JavaScript applications since these events can occur at any time. Immutable data structures make the development process easier by explicitly delineating when application data can be modified.

ClojureScript and JavaScript each share some common characteristics, so the difference between program structures is not as vast as the difference between Clojure and Java. ClojureScript and JavaScript are both dynamic, functional languages, so many concepts can be expressed with the same degree of conciseness. ClojureScript has an additional advantage over JavaScript, though, since it uses the same macro system provided by Clojure. This allows developers to extend the capabilities of the compiler. Well-designed macros allow repetitive, boilerplate code to be abstracted away, resulting in much more concise source code.


ClojureScript enforces a specific organizational structure for code called namespaces. All libraries outside of the core language must be referenced by their unique namespace (similar to Java packages). The lack of an equivalent structure can be a pain point for JavaScript developers. An interesting scenario involves the use of the popular JavaScript libraries jQuery and Prototype. Each of these libraries defines a global symbol ‘$’. JavaScript code using both of these libraries cannot differentiate between calls to ‘$’ in jQuery or Prototype without writing additional code to manage this symbol conflict. ClojureScript’s namespaces conveniently avoid such conflicts.

Development Tools

The ClojureScript community has contributed a number of tools to increase productivity during application development. The tool ‘cljsbuild’ leverages the Clojure build tool ‘lein’ to automatically download third-party dependencies and then compile ClojureScript code into JavaScript. It has a convenient feature to automatically recompile when it detects changes to the source code.

One of the most innovative development tools for ClojureScript is called the “browser REPL.” The acronym “REPL” stands for “Read-Evaluate-Print-Loop.” It is a concept that is found in a number of development languages and usually consists of a text prompt that accepts source code to be instantly evaluated. The browser REPL is an extension of this idea and will evaluate ClojureScript code in the context of a running web browser, skipping the usual compile/refresh process. While this is certainly a valuable tool, most major web browsers provide a similar console for evaluating JavaScript code. The ClojureScript community has taken this concept a step further and integrated the browser REPL with a number of popular text editors. This allows editing of currently executing ClojureScript source code directly in the browser from the comforts of a full-featured text editor. There are few other development environments that offer such a dynamic experience.

Language Innovation

The Clojure development community has a reputation for producing innovative new libraries to resolve issues across all types of problem domains. A recent example of this is a new library to do asynchronous programming called core.async. The main architect of the library (as well as the creator of Clojure) describes the library here. To summarize, JavaScript applications have traditionally used callback functions to handle asynchronous events like mouse clicks or responses from AJAX calls. This library has the potential to simplify how ClojureScript applications are structured, providing a nice alternative to callback functions. Due to the compiled nature of ClojureScript, in addition to the macro system’s ability to create abstractions out of portions of code, a library like core.async can provide new syntax without introducing any drastic changes to the language or the runtime environment. In contrast, the standard that JavaScript is based on, called ECMAScript, moves at a much slower pace in order to standardize any new syntax. A lot of the features available today in ClojureScript cannot be introduced in the ECMAScript standard until a large group of stakeholders agree upon them. This is often necessary due to the importance of stability in future JavaScript engines, but it often leaves JavaScript developers wanting for more powerful language features for constructing applications.

As browser applications become more complex, JavaScript developers must expend additional effort to produce correct, maintainable code. ClojureScript provides numerous features for dealing with application complexity and creating clear and concise code. I encourage readers to consider using ClojureScript for your next web-based project.

Author: bridge360blog

Software Changes Everything.... Bridge360 improves and develops custom application software. We specialize in solving complex problems at every phase of the software development lifecycle, removing roadblocks to help our clients’ software and applications reach their full potential in any market. The Bridge360 customer base includes software companies and world technology leaders, leading system integrators, federal and state government agencies, and small to enterprise businesses across the globe. Clients spanning industries from legal to healthcare, automotive to energy, and high tech to high fashion count on us to clear a path for success. Bridge360 was founded in 2001 (as Austin Test) and is headquartered in Austin, Texas with offices in Beijing, China.

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s