
Why I'm ditching Clojure for JavaScript - _diyu
https://sdegutis.com/blog/2017-08-30-why-im-ditching-clojure-for-javascript/
======
yogthos
>These days I prefer writing in modern JavaScript (ES2015 and better). With
destructuring, lambda syntax, extended object literals, spread syntax, and
just the general language overhaul, it's basically a tie with Clojure's terse
syntax.

One of the biggest advantages I find with Clojure syntax is that there's very
little of it, and it's much more consistent than JavaScript. Sure, you can
often write code that's just as concise in Js nowadays, but there are a lot
more gotchas as well. The more syntax quirks you have, the more likely it is
that you'll misread something and have a subtle bug slip in. I value
simplicity and cleanliness of the language as much as its expressiveness.

The article also doesn't explain why the author moved to JavaScript. It sounds
like the author didn't want to use the JVM, but ClojureScript works just fine
on Node. My team is using Macchiato [https://macchiato-
framework.github.io/](https://macchiato-framework.github.io/) for some smaller
projects in production right now.

I'd be interested in reading more about the specific reasons, and what
problems the author ran into with the Clojure stack. That would at least help
address the issues going forward.

~~~
_sdegutis
Author here. My main reason for moving away from Clojure and ClojureScript,
and not towards Haskell or OCaml or even TypeScript (yet!) but rather towards
modern JavaScript, is because in general I've been learning to appreciate the
Path of Least Resistance in software development. I wrote another aspect of
this in Age of the Polyglot[1], which focuses on the friction when bridging
loosely-compatible tools, but there's other friction points to the non-
mainstream ecosystems, like having a stagnant or decaying community, lack of
libraries, etc. A lot of active development seems to be happening in the Node
world in the past 5 years, and although there's probably a ton of crap,
there's also a ton of gold, and that's kind of what happens when you have a
thriving community.

[1]: [https://sdegutis.com/blog/2014-08-18-age-of-the-
polyglot/](https://sdegutis.com/blog/2014-08-18-age-of-the-polyglot/)

~~~
yogthos
My team has been using Clojure for about 7 years now, and we started using
ClojureScript about 2 years ago. We're certainly finding it to be the path of
least resistance compared to keeping up with Js. For example, we've been using
Reagent for the front-end, and it's stayed the same all this time. Even as
React itself keeps changing, all we have to do is update the library version,
and everything just keeps working.

Keeping up with the way Js world evolves is absolutely bonkers in my opinion.
By the time you finish writing an app, the whole stack becomes outdates as
people jump onto new hot thing.

Even if you stick with something like React, the practices around it keep
shifting, you now have Redux and Relay, and god knows what else people will
come up with next week. Having a stable development environment is a big
benefit in my book.

I'm also not seeing any problems with Clojure community being stagnant or
decaying. It keeps growing steadily, and the library ecosystem is quite
excellent at this point. Since Clojure embraces the host platform, you always
have access to native libraries as well. If a cool library gets developed in
Js or Java, it's immediately available in Clojure.

Node has a lot of hype, but I haven't seen anything developed on Node that's
not available on the JVM. The only advantage of Node I see is that it takes
less resources. Having actually developed some ClojureScript apps on top of
Node, I think that it's a strictly inferior experience. Callbacks are much
harder to work with than threads, and even promises and async result in much
gnarlier code. Given my experience with it, I would only use Node for very
simple applications.

~~~
_sdegutis
> Keeping up with the way Js world evolves is absolutely bonkers in my
> opinion. By the time you finish writing an app, the whole stack becomes
> outdates as people jump onto new hot thing.

I definitely agree which is why I haven't sunk a whole lot of time into
learning any of these in particular just yet. I've stuck with vanilla JS for
most front-end needs and Vue.js when I need something slightly more complex,
with no build phase.

> Since Clojure embraces the host platform, you always have access to native
> libraries as well. If a cool library gets developed in Js or Java, it's
> immediately available in Clojure.

True but I don't see a whole lot on that front in the JVM world either.
There's a few libraries that pop up here and there, but most Java work I've
ever seen is done using existing tools and frameworks, unfortunately.

> Node has a lot of hype, but I haven't seen anything developed on Node that's
> not available on the JVM.

I look at it the other way around: In an _incredibly_ short time span, NPM has
pretty much covered every library that the JVM has.

> The only advantage of Node I see is that it takes less resources. Having
> actually developed some ClojureScript apps on top of Node, I think that it's
> a strictly inferior experience.

From a technical perspective, Node is probably inferior to JVM in most ways,
yeah. But not in ways that matter significantly. Lately I've been considering
social aspects to be a lot more important than technical aspects, though. I
mean, Rails got popular while sitting on top of _an AST-traversing Ruby
interpreter_. At the end of the day, as long as it's semi-usable, hype and an
active community are probably more important than all the other facets of a
language, at least for most web apps.

~~~
yogthos
>true but I don't see a whole lot on that front in the JVM world either.
There's a few libraries that pop up here and there, but most Java work I've
ever seen is done using existing tools and frameworks, unfortunately.

I still don't understand what the problem here is. Can you explain a concrete
business problem you were trying to solve and found Clojure inadequate for.
What was the scenario where you couldn't find a library for a specific task,
or couldn't solve a problem because the language was deficient.

>I look at it the other way around: In an incredibly short time span, NPM has
pretty much covered every library that the JVM has.

Threads is a great example of something that Java has and makes a huge
difference in the developer experience. Having to chain async calls for every
single thing you do is absolutely insane in my experience. Following code
becomes a lot harder, debugging is a nightmare, and passing errors around has
to be done explicitly in error prone fashion.

>From a technical perspective, Node is probably inferior to JVM in most ways,
yeah. But not in ways that matter significantly.

See above.

>Lately I've been considering social aspects to be a lot more important than
technical aspects, though.

Sure, let's talk about social aspects. Clojure community is primarily composed
of very experienced developers and that directly reflects the quality of
tooling and libraries available. Last I checked Clojure community is very
active and it's not going anywhere. It's used at places like Amazon, Boeing,
NASA, and Walmart for mission critical tasks. I certainly value quality over
quantity here.

------
_sdegutis
I feel similarly about ClojureScript. It's a neat proof-of-concept, but I'm
not really sure what it adds over regular JavaScript (or at least Babel +
Webpack) these days.

~~~
yogthos
My team finds that it adds a lot. For starters, it's a much cleaner and
simpler language. This means that you have a lot less mental overhead working
with it.

It encourages good practices by defaulting to immutability. This naturally
leads to code that can be reasoned about in isolation.

I find the tooling is superior. Leiningen lets me do the same thing as a grab
bag of Js build tools, such as dependency management, building, packaging, and
so on.

There's still no equivalent to Figwheel in JavaScript workflow. The
productivity of being able to see changes as you're working without having to
reload the page and rebuild state can't be overstated.

Reagent/re-frame combination much cleaner than React itself in my opinion. It
also avoids much of the complexity in React as described here
[https://purelyfunctional.tv/article/react-vs-re-
frame/](https://purelyfunctional.tv/article/react-vs-re-frame/)

~~~
_sdegutis
> For starters, it's a much cleaner and simpler language. This means that you
> have a lot less mental overhead working with it.

I haven't seen much code that uses the bad aspects of JS, or at least exposes
it in library APIs. You can just stick to the good parts of JS and have the
same benefit. Clojure also has its quirks, btw. Every language will.

> It encourages good practices by defaulting to immutability. This naturally
> leads to code that can be reasoned about in isolation.

The language may encourage it, but given that none of the JS libs I've used
mutate anything I give them, it sounds like the benefits of immutability have
spread enough that mutation is no longer a problem in practice.

> I find the tooling is superior. Leiningen lets me do the same thing as a
> grab bag of Js build tools, such as dependency management, building,
> packaging, and so on.

If you write a good set of config files with something like Webpack, it's
fire-and-forget. And in practice, Leiningen isn't all that simpler than JS
alternatives. Trying to understand the sample project.clj for a real-world
ClojureScript project was kind of a nightmare for me.

> There's still no equivalent to Figwheel in JavaScript workflow. The
> productivity of being able to see changes as you're working without having
> to reload the page and rebuild state can't be overstated.

We'll have to agree to disagree. I can make changes to my site and the page
reloads live with only 14 lines of vanilla JS code on the front-end[1] and
back-end[2] each. If I need to make changes _while keeping state_ instead of
reloading (which I haven't really seen a need for) I'm sure I can whip
something up using `eval`. Plus even if you follow the Components architecture
and avoid global state, there are still situations where you have to reload
the page from scratch.

> Reagent/re-frame combination much cleaner than React itself in my opinion.
> It also avoids much of the complexity in React as described here
> [https://purelyfunctional.tv/article/react-vs-re-
> frame/](https://purelyfunctional.tv/article/react-vs-re-frame/)

That may be true, but that doesn't prevent equivalent libraries to Reagent/re-
frame from being created in JS. And maybe there already is an exact copy of
that in JS somewhere. React may be the king in this space for now, but there
are lots of alternatives or plugins while sticking to JS.

[1]:
[https://github.com/sdegutis/sdegutis.com/blob/master/src/tem...](https://github.com/sdegutis/sdegutis.com/blob/master/src/template/reload.js)

[2]:
[https://github.com/sdegutis/sdegutis.com/blob/master/index.j...](https://github.com/sdegutis/sdegutis.com/blob/master/index.js#L329-L346)

~~~
sheepmullet
> I haven't seen much code that uses the bad aspects of JS

> The language may encourage it, but given that none of the JS libs I've used
> mutate anything I give them

> If I need to make changes while keeping state instead of reloading (which I
> haven't really seen a need for)

Speaking as an enterprise JS dev the kind of apps you are working on sound
nothing like the kind of apps I work on.

I work with a lot of poorly written JS code, a lot of mutable state, and pages
with lots of complex state setup.

In fact the state setup is typically so bad developers rely upon unit tests
and only check the UI on feature complete.

~~~
_sdegutis
Sorry to hear that. And that kind of code damage sounds pretty typical from
most projects I've seen in open source and heard about through people I've
talked to, no matter what language these projects use. It must just be that we
all learn the hard way and usually during work hours what works and what
doesn't. In cases like this, Clojure can help somewhat by its saner defaults,
but I've seen some _really_ terrible Clojure code too, that has many of the
same problems.

------
Scarbutt
Tbere's also a reddit.com/r/clojure thread FWIW.

