What is the difference between Clojure and ClojureScript

Getting started in ClojureScript

Functional programmers also want to use their preferred functional language in web development on the browser. JavaScript has its roots in functional programming, but the language also has an object-oriented and various ugly sides. For this reason there is now a small industry of compilers from other programming languages ​​to JavaScript, for example for OCaml, Scala, Haskell and Racket.

Today we're looking at a particularly popular functional language targeting JavaScript: ClojureScript.

ClojureScript is a dialect of Clojure, and thus a dynamically typed Lisp dialect with a special emphasis on purely functional data structures. ClojureScript is not identical to Clojure - there are a number of subtle differences, e.g. in the representation of numbers, in field / method access or in macros. In this article, we are primarily interested in a quick introduction to develop a feeling for the language, its ecosystem and the connection of JavaScript frameworks. Programming with ClojureScript is really good fun, especially for people like me who can hardly speak JavaScript.

As with Clojure, Leiningen, the standard build tool for Clojure projects, is essential for ClojureScript development. Leiningen allows the creation of a project skeleton with the help of templates stored on the Internet. We need a minimal ClojureScript project that is done with one command:

is the name of the template - the command makes a directory called in which the project is located. This can be put into operation as follows:

The script ensures that the ClojureScript code in the project is compiled according to JavaScript and then keeps an eye out for changes. If it finds any, it recompiles.

Once it has run through, the file (also generated by) in the project root directory is ready to be opened with the browser. The whole thing is configured in the Leiningen configuration.

The actual web application is in the file. Only the following meager program is ready-made:

The first line is the namespace declaration known from Clojure. ensures that and the like print in the console of the browser. It is therefore advisable to open the JavaScript console in the browser. (In Firefox about, for example, in Chrome about.)

The code is loaded from:

Finally, the entire generated JavaScript code is loaded from, along with the required libraries.

Since the direct manipulation of the DOM from JavaScript is not much fun, the use of a GUI framework is also recommended in ClojureScript. For example, React, recently published by Facebook and Instagram, fits particularly well, which is particularly close to the concepts from functional programming:

React-Components are objects with any internal state that you can render in a GUI at any time by specifying a method. This delivers a virtual DOM object that React then transfers to the real DOM. React only transfers the parts that have changed, which makes the framework extremely fast.

As an example, we will make a very simple comment application in which a list of comments - each author and text - are displayed and new comments can be added. In preparation, we first have to add to a line that includes React:

Here is the definition for a React component class for a single comment in ClojureScript:

Programs with the prefix can approach objects from the JavaScript namespace. Accordingly, the function belongs to React - it expects a JavaScript hash map that defines various aspects of a component. In the simplest case like here, this is just a single function. However, it should be noted that ClojureScript maps cannot be used directly as JavaScript hashmaps. (In ClojureScript, a map is also a persistent data structure like in Clojure.) The prefix ensures that the following map is created as a JavaScript hash map.
The keyword key becomes the key in the hash map.

React stipulates that there should be at least the entry, and that should be a function that returns a virtual DOM object. To do this, the comment object must know who is the author and what the text of the comment is. In React, that's what Properties responsible for a component, which can be supplied with the creation of the component, also in the form of a hash map, for example in the following form:

Within the function, the properties are in the "This" field. In ClojureScript "This" has to be linked explicitly to an identifier: The form links it to it. Then extracts the contents of the field. (This distinguishes field accesses from method calls that have none.)

The calls construct the DOM virtual object. The s each say that there are no attributes for the elements. In HTML, the body of a component would look like this:

The class works in a very similar way for a whole list of comments:

The idea is that such a component is instantiated like this, for example:

Here, too, it should be noted that a ClojureScript vector is not a JavaScript array - the React DOM constructors want to see arrays. Therefore the conversion with.

Next we make a component that allows entering a new comment. For this we create a form with two text fields - for the author and text of the form:

The two elements in the method each have attributes with names for the elements: these are there so that the callback of the form can access the contents of the text fields. The callback is in the function, which is also in the hash map when the component is constructed. React puts it under the same name in the component object so that it can be accessed with.

The function can then access the field of, which contains all DOM elements that have received an attribute in.
The field is the element with value, corresponding to. The method then delivers the corresponding real DOM element, in which the field then fetches the corresponding text.

But what to do with the new comment? It should of course be added to a list of all comments, which is outside the component. The function therefore assumes that there is a function named under the properties that does this job. This must then be supplied with the creation of the component. This opens with the new comment.

Important: must deliver so that the browser sees the submit event as finished and does not try to deliver the form to the website.

Finally, we'll write a component class to put it all together. This class has now (as the only one) Status, namely the current list of all comments. For the management of the state, React wants to see a method called that sets the initial state. As with the properties, the state must be a hash map. The function gets the initial state from the properties (which we still have to pass accordingly):

It now installs a and a component and passes the method in the properties that follows:

Finally, the method uses the React method to add the new comment to the comment field in the state.

Finished! Well, almost: In order to see something in the browser, we have to hang another component in the DOM:

In order for this to work, we still have to put a placeholder with field in it. It then looks like this:

Now ready!

You can get even more out of the elegant React model by using ClojureScript through purely functional programming. Several ClojureScript frameworks have been developed around React, for example Om and Reagent.

The complete code for this example is on github or as a zip file here.

Have fun trying!