Language features and semantics

Actually, you can change immutable data structures, it’s just that
‘change’ does not mean the same thing. In this case, changing means
making a new data structure, that has some differences to the one you
started with.

In JavaScript, you’re already doing this when working with strings,
booleans, and numbers: incrementing a number is making a new number;
appending to a string is making a new string.

So you should really not think of immutable data structures as
constrained containers, but as composite values.

You should feel reassured by the fact that persistent data structures
are hard to implement efficiently. There are some sophisticated
algorithms doing the heavy lifting for you behind the scenes so you can
have your cake and eat it too. This is similar to Garbage Collection: an
algorithmic innovation which yields semantics that are less natural for
computers and more natural for humans.

This is all nice, but how will programming with values make my life
better?

The most immediately visible benefit is that you will never have to use
brittle techniques like defensive copying, cloning, etc., because you’ll
never have to worry about some other part of your code mutating your
data from under you.

Let’s see a concrete example. Imagine you have a Person model in your
web app, and a component that lets you edit and submit changes to the
value of the Person’s fields. When programming with values, it is
trivial to achieve the following functionality:

start editing from the current version of your model at some point
in time

when editing, have your modifications be only local to your editing
component, without affecting the rest of your app

conversely, have your app see changes to your model from an external
source (e.g updates pushed from your API), while your local editing
process still deals with the version it had started with

support undos and redos while editing

when submitting your changes, optimistically change the value of
your model in your web app so that your changes are immediately visible,
and revert them if the server comes back to you with an error.

More deeply, there are strong reasons to believe that values are a much
more natural fit than mutable data structures for making information
systems. This is particularly true in network-intensive applications
like web apps (values are what you get from / send over the wire; it’s
not like your AJAX call was going to give you a data structure that lets
you mutate your database). There’s a
talk which makes an
excellent case for values.

Finally, even without considering the benefits of value-based
programming, you’ll find that ClojureScript’s collections are just very
powerful and pleasant to use, thanks to a very complete standard
library.

ClojureScript atoms are superior to JavaScript variables in the same way
that JavaScript functions are superior to, say, Java methods: because
they’re first-class. They can be passed to functions, referenced by data
structures, and abstractions can be built atop them. In addition, atoms
can be observed.

You’ll find that you use much fewer ClojureScript atoms than you did
JavaScript variables. The combination of atoms and immutable data
structures allows you to manage your state in a few key places, instead
of having it strewn all over your programs.

A lot of people define macros as an easy way to customize the first
steps of compilation. This is the kind of definition you understand only
once you’ve used macros, so let’s explain it differently.

A macro lets you specify some transformation of your code; using a macro
called my-macro is like saying to ClojureScript: ‘when I write
(my-macro <this nice-looking code>), I mean
`(<this more tedious code>)’ . In the same way that functions factor
out parts of the execution of your programs, macros factor out parts of
the writing of your code.

As a consequence, when you have macros, you can always make your calling
your code as comfortable as possible, because the syntax will never get
in your way.

Indeed, even in the ClojureScript community it is considered bad style
to use a macro when you don’t have to. ClojureScript application
developers very rarely write macros, because most of the time a function
can also do the job, and is easier to reason about.

But from time to time, you need to make a conceptual leap that only
macros can achieve, because the tedium in the syntax cannot be mitigated
with functions, or because it requires code analysis.

Macros are like planes. You don’t want to take a plane everyday to go to
work. But from time to time, planes allow you to reach another continent
in a matter of hours, so we’re glad we have them.

Some people are bothered by the number of parentheses that Clojurescript
code requires. You’ll find that they’re not a problem once you get used
to
Clojure
indentation conventions. It goes without saying you should use an
editor that will help you match parentheses, braces, and brackets. If
you also use an editor that will help format your code for you, you’ll be able to see
immediately if you’ve made a mistake with parentheses.

ClojureScript has very good JavaScript interoperability. ClojureScript
function are regular JavaScript functions. The language provides
primitives to access native browser objects, access and set properties
of objects, create and manipulate JavaScript objects and arrays, and
call any JavaScript function or method.

You can also write functions in ClojureScript and call them from
JavaScript.

ES2015, ES7, etc. bring a lot of expressiveness to JavaScript (arrows,
generators, destructuring, …​) while addressing several of its
shortcomings and deficiencies (modules, block scope, …​). Does this not
make languages like ClojureScript pointless?

Comparing programming languages by listing their features is a dangerous
exercise, but let’s do it anyway. Most of the syntax enhancements newer
ECMAScript versions bring, Clojure provides. The following table lists
recent ECMAScript features and their ClojureScript equivalent.

ClojureScript is not class-based
by design; use data types and
protocols to get the good parts of Object-Orientation. See
next section for more details.

Template Strings

ClojureScript strings are multi-line, and the absence
of commas makes using the str function for concatenation very natural;
you can also use C-style format from the Google Closure library.

Destructuring

Available, also supports nesting and function
parameters.

Default and rest arguments

Fully supported

Let and const

these are the exact semantics of ClojureScript’s let.

Iterators and For..Of

Seq abstraction, which is implemented by all
default collections.

Generators

Lazy seqs

Sets and Maps

part of the standard library (as persistent data
structures), allow for arbitrary keys.

Proxies

Not relevant

Symbols

By design, ClojureScript is against information hiding, so no
private members. Keywords can be namespaced, reducing the potential for
conflict in map keys. Protocols let you extend the behaviour of existing
data types without new visible members.

Math + Number + String + Object APIs

Similar functionality in both
the standard library and the Google Closure library.

Number literals

there are literals for any base, with special syntax
for octal and hexadecimal (and of course decimal)

Ecosystem

It’s ClojureScript itself! ClojureScript comes with an excellent
collections library. All the collections functions you know and love are
there (map, reduce, filter, remove, …), and they work on abstractions,
which means they are not restricted to javascripts objects and
array-likes.

You won’t find an equivalent of AngularJs or Backbone in ClojureScript.
This is actually a good sign. In great part, what motivated these
client-side frameworks was JavaScript’s lack of modularity, primitives
and a decent standard library.

ClojureScript as a platform addresses these issues, and relies on the
Google Closure library to address browser inconsistencies. The other
concerns of building applications (e.g templating, server communication,
routing etc.) are addressed by composing together special-purpose
libraries.

To get started on ClojureScript projects, the ClojureScript Wiki
provides several project templates, as well as a catalog of libraries.

ClojureScript, as a programming language, is very mature. Clojure was
carefully designed for several years before being made available to the
public in 2008. When ClojureScript came out in 2011, Clojure had been
tested and proven for several years on the JVM. This, along with the
combination of Clojure’s emphasis on simplicity and the fact that macros
eliminate many difficult language design decisions, has led Clojure as a
language to reach stability in only a few years.

If the transformations JavaScript is going through are a problem to you
(new language features, paradigm shifts in the community, convention
changes in programming shops, and all the changes they cause in the
tooling and libraries), ClojureScript may be a nice place for you.

Of course, the language is not everything, and the ClojureScript library
ecosystem will go through important transformations in the coming years.
But one should note that this is happening in the JavaScript ecosystem
as well, as shown by the massive adoption of paradigm-shifting libraries
like React and Falcor, and the changes undergoing application platforms
and requirements.

React and Flux

Yes, almost everyone in the ClojureScript community uses React because
of the deep synergies it has with functional programming as embodied by
ClojureScript. In fact, a lot of ClojureScript programmers think of
ClojureScript as the best way to leverage React.

The rich collections library, advanced control flow operators (such as
cond, case, when, let, if-let, pattern matching etc.), and the
fact that everything is an expression enable you to write rendering
functions in a very direct and declarative way (you won’t have to lay
out a bunch of intermediary variables).

Flux is very straightforward to implement in ClojureScript, thanks to
the combination of persistent data structures and managed references
(atoms). This is part of the raison d’être of influential libraries like
Om.

In many respects, ClojureScript is leading the way for the wider
React/Flux community, as shown by the progressive adoption of immutable
data structures, the ‘all state in one place’ principle, and other
functional techniques.

Yes! Besides the fact that you can just use React in ClojureScript, the
most popular ClojureScript wrappers to React (Om, Reagent and Quiescent)
all let you include React components without any effort.

Tools

You’ll probably find that structural editing is more practical than what
you’re used to, because it naturally lets you manipulate the building
blocks of your code (i.e expressions, not lines or words).

Yes. Most ClojureScript developers use Leiningen
to manage ClojureScript projects, which takes care of dependencies
loading, packaging, and has plugins for front-end development workflow
(CSS pre-processing, assets minification, etc.). Another popular tool is
Boot.

In particular, ClojureScript with Figwheel is arguably the
state-of-the-art of interactive front-end development, thanks to live
code reloading and the ClojureScript REPL.

dead-code elimination, i.e code which is not used is removed. (This is
what enables the library to be comprehensive: you don’t have worry about
the extra bytes when adding functionality.)

The majority of JavaScript developers have rejected Google Closure
because of a major drawback: for dead-code elimination to work, they had
to follow strict discipline about the JavaScript they write (in
particular, it ended up looking a lot like Java).

You don’t have this impediment when using Google Closure from
ClojureScript, because the ClojureScript compiler emits JavaScript that
is optimized for Closure out of the box. This means you can reap the
benefits listed above without making any compromise on your language
semantics.

Dead-code elimination is a great convenience for the application
developer, but it has even deeper benefits for the development of the
ecosystem. Library authors no longer have to make
functionality-vs-weight tradeoffs because the users only get the bytes
they use.

Platform

First, ClojureScript targets all major JavaScript engines. Therefore,
you can run ClojureScript on NodeJS.

However, you won’t find many examples of ClojureScript for writing
NodeJS servers. For a variety of reasons, people tend to prefer the
original JVM Clojure on the server (the library ecosystem is more
mature, and it does not force you to write asynchronous code).

Since Clojure 1.7, it has become very easy to write Clojure code that
targets both the Java and JavaScript runtimes.

However, when that approach fails (in the cases where you need to rely
on JavaScript-specific functionality on both server and client), people
tend to turn to Nashorn, the JavaScript runtime embedded in Java 8.

Practical use

ClojureScript has excellent support for traditional JavaScript debugging
techniques: you can set breakpoints in your source code, get
ClojureScript stacktraces, etc. This is possible thanks to very well
engineered source maps, which work even on production code with advanced
minification.

In addition to this, REPL-driven development and hot-code reloading
bring a whole new dimension to this, by enabling to test and modify
stateful programs without erasing the conditions for a bug.

Icing on the cake: Macros help you here too. A typical JavaScript
debugging technique is to insert console.log calls in the middle of
your code, but this quickly gets tedious and intrusive.

For example, let’s assume you have this code, and suspect the myFun
function is faulty:

var result = x + myFun(y);

What you would have to do is:

var z = myFun(y);
console.log("myFun(y) : ", z);
var result = x + z;

In ClojureScript, you can define a spy macro that does the same thing
in a very lightweight manner. So the equivalent ClojureScript code:

Obviously, since ClojureScript is abstractions on top of JavaScript, it
must be slower, especially because of persistent data structures.

Actually, the creators of ClojureScript had the pleasant surprise that
JavaScript features is a very natural and direct foundation for
ClojureScript’s semantics (for instance, ClojureScript functions are
regular JavaScript functions; ClojureScript protocols map to JavaScript
prototypes in a very straightforward way). As a result, ClojureScript is
quite fast.

ClojureScript’s persistent data structures are obviously slower than
JavaScript arrays and objects, but not as much as you’d think, because
they were not implemented in a naive way (it’s not cloning or
copy-on-write). Here’s a
benchmark to give
you an idea.

Learning ClojureScript

This varies significantly depending on people’s programming experience
and aptitudes.

If you’re a JavaScript developer, you’re in a good starting place to
learn Clojure(Script) - more so than if you program in a classical
language such as Ruby or Java - because JavaScript has already educated
you to first-class functions, dynamic typing, conveying information with
data structures (not classes), and organizing your code in namespaces
(not class hierarchies).

Conceptually, you need to learn fewer things in ClojureScript that in
JavaScript to get productive, because you don’t have to learn to avoid
all the traps of JavaScript. The REPL and the fact that documentation is
included in the language play a critical role in speeding up the
learning process.

In all likelihood, the big challenge will not be to assimilate new
concepts, but to forget old ones. As Yoda put it: ‘You must unlearn what
you have learned [about imperative and object-oriented paradigms]’; this
makes it harder for experienced programmers. Having said that, if you’ve
been developing with JavaScript in a near-to-functional style (as
advocated e.g by Douglas
Crockford), this won’t really be a problem.

I heard functional programming is only accessible to people who have a
Ph.D.

You don’t need to know Category Theory, Monads, etc. to use
ClojureScript. For 99% of the work you’ll be doing, the programming
concepts you’ll need are those you’re already using in JavaScript
(dynamic typing, functions, data structures).

Community

There is, and it’s growing fast. Actually, the community is often what
people love most about Clojure. The Slack and various mailing lists are
very active, and people are very responsive whenever you need help.

What characterizes the Clojure(Script) community is its combination of
pragmatism, inventiveness, high quality standards, and wise leadership.

I’m wondering if the Clojure people are not just in love with some
elegant ideas, without being lucid about their actual added value in the
real world.

Most people in the Clojure community went through a sort of epiphany
when exposed to the ideas of its creator (notably through some excellent
talks like Simple
Made Easy and The Value
of Values), and felt greatly rewarded when adopting their incarnation
in Clojure. As a consequence, we can sometimes be enthusiastic to the
point we don’t seem very objective.

But you should know that practicality and pragmatism have always been
core values of Clojure, which motivated fundamental decisions like
targeting the popular platforms which are the JVM and JavaScript
runtimes, as well as the design decisions of sacrificing some functional
purity as compared to other languages. You can tell that the Clojure
community has kept true to this spirit by all the efforts they have put
in developing practical tools and extending Clojure’s reach to a broad
spectrum of platforms.

Misc

Clojure is based on the fundamental belief that aiming for simplicity
can dramatically empower programmers. The counter-intuitive implication
is that getting rid of sophisticated tools and techniques will actually
make you more effective. You won’t believe it until you experience it.