Which piece of code do you think makes ClojureScript significant?

Try something as simple as a serialized edn string with record namespace :

(cljs.reader/read-string "{:name \"Pankaj\"}\n")

The above would work on lumo and planck but not if you bring a cljs repl using clj -Sdeps '{:deps {org.clojure/clojurescript {:mvn/version "1.9.946"}}}' -J--add-modules -Jjava.xml.bind -m cljs.repl.node

This is getting way too off-topic. It works just fine in my node repl? Did you maybe miss a (require 'cljs.reader) first? Feel free to send me a direct message to help you troubleshoot this. Or open another thread, we should not hijack this one.


In fact, a patch worth considering would be to alias clojure.edn to cljs.reader to ameliorate this confusion.


I am one of those javascript guys who happens to hate Java. My first approach to programming was through video game programming on a language that mixed C and pascal. After that I have programmed in C, C++, php, python, javascript, bash, ClojureScript, Haskell and of course Java, and it happens that there is no language that I hate most than Java . My problem is not with the JVM at all, and I don’t think any smart person has anything against it neither, it’s an impressive piece of machinery. The problem (and makes sense, of course) is that everything related to the JVM involves in some way or another Java, which is the bad part: unless you are an end-user you will have to write or read some Java. I was first attracted to Clojure by the idea of writing code for the two mainstream virtual machines of nowadays, but after developing some toy projects with it I came to the conclusion that you need to know the host language very well to be able to use it. This is true for me in the case of javascript, but it will never be for Java. In fact being able of writing stuff that will run on the JVM without writing any Java was one of the main selling points, but seems to be impossible. That leaves me with ClojureScript alone, so I think that finding motivation to stick with Clojure even if your are not going to target te JVM is important for many people.
I have to admit that the weird syntax was also attractive to me, but I don’t think we can shell this to many people :smile:


I think it’s important to be able to read the host language and be familiar with its idioms, and of course the ease of doing that scales up with ones reading proficiency in the host language.

I think the most Java I’ve written in a Clojure context was some throwaway code demonstrating a minimal example of a bug in a Java package over which I maintain a Clojure wrapper. The Java was only necessary because I wanted to literally “speak their language” when reporting the bug.

I think it’s quite rare for Clojurists to write any Java for their Clojure projects. Have you found it necessary?

Sorry if I gave the impression that I wrote anything apart from configurations in Clojure. I only tried ClojureScript under nodejs. I didn’t need to write javascript code, but I had to write some code that was just javascript with a different syntax. Based on that experience I extrapolated that to Clojure. Maybe my judgment was not fair knowing that ClojureScript on node was not the primary target of the community and that may be the reason why I had to write so many interop by hand.
Maybe I am mistaken and it is different for Clojure, which is the original language and server side java is the main target

To answer the original question, for me, the killer feature of ClojureScript is the way atoms are built into the language and enable an observer pattern that works flawlessly and with the full complement of the built in language features.

This feature does what redux + immutable.js, mobx, and similar libraries try to do in JS. But these libraries all require you either to conform to a subset of the language (e.g., in mobx you have to manipulate arrays carefully) or require a giant amount of boilerplate and careful coding conventions (redux).

In cljs, you can just manipulate the state and everything else happens automatically. It seems to me that it is just not that easy to replicate this feature in javascript in a natural way.


In cljs, you can just manipulate the state and everything else happens automatically. It seems to me that it is just not that easy to replicate this feature in javascript in a natural way.

I would second this, especially with re-frame with its defined one-way dataflow everything is so much more understandable and easier to follow.

1 Like

I guess I’m starting to realize, maybe most of the ClojureScript trade-offs were due to its compiler being Clojure only. The special handling of macros, the fact very little is reifiable, the lack of eval, the more complicated repl setup, etc.

Now that self-hosted ClojureScript is real, do you think we could see some of those trade-offs be revisited? Maybe once the JavaScript Google Closure variant is out of alpha? Like reintroducing reified vars and namespaces, adding eval back, letting macros live in cljs namespaces, etc.?

Let’s not conflate quirks with explicit design choices. Self-hosted ClojureScript is impractical for most web applications due the order of magnitude increase in the base payload. Making self-hosted ClojureScript act differently is a portability liability.

Suffice to say the semantics of ClojureScript haven’t changed in many years and they aren’t going to.

1 Like

Fair enough, I edited my post.

I’ll work to educate better, and most of these are honestly small, you just have to know about it and how to do it the ClojureScript way instead.

I think this two tweets are very good ways of being positive about clojurescript:

And the best part is that they from the official guide!


I get where you’re coming from (switched to cljs 2-3 years ago from react+webpack). It’s not “just” hot reloading though, with figwheel you get a REPL into the app running in the browser. That just comes with the figwheel setup, and it integrates very well with Cursive in IntelliJ (switches the REPL to cljs mode) and Emacs, I imagine, for those with enough grit :wink:

This means that I can evaluate stuff in my REPL that directly uses re-frame’s “live” db atom, and events, subscriptions as well. I can trigger DOM events, or query the DOM, play around with my own namespaces and functions, mess around with Google’s Closure library, and so on. All the benefits of the REPL-workflow combined with hotreloading … unmatched, so far. Don’t forget that you’re getting all the other benefits from using Clojure in the first place, for which you’d need strong conventions, libraries and/or tooling set up (Immutable.js and friends) in webpackland.


I get the sense that many Javascript refugees just use hot-loading, which is familiar from their previous ecosystem, without ever realizing the tremendous advantages of also having an editor-connected REPL. :man_shrugging:t2:


In my opinion, part of the reason for this is that

  1. Getting a CLJS repl to work is incredibly difficult and conceptually difficult for newcomers like me to understand given all the multitude of cooperating libraries and servers and clients and keeping it distinct from the CLJ repl.

  2. To be good in a repl you need to understand the namespace system well. I feel constantly stymied at trying to get the right commands issued so that I can actually call functions from other namespaces.

So hot loading is a godsend. I just use console print statements as a slightly slower repl where my editor does the “R” and the browser does the “EPL”.


It’s probably a good idea to understand the namespace system well in any case if you are at all serious about writing clojure(script) programs.

Anyway, I absolutely agree that the tooling could be better, but I think in addition that there’s a failure to really teach the whys and hows of the interactive style of programming, which is a shame. We’ve tried to make a teaching environment to help, but ultimately direct mentorship might be the best model here.


Like @dave.liepmann, in my seven years of production Clojure, I don’t recall having to write any Java code at all. With some libraries that I’ve chosen to use, I’ve had to rely on the interop syntax more than I would have liked – but, trust me, the Clojure-with-interop code was still a fraction of the size of the equivalent Java and much, much more readable!

1 Like

Scala.js is not Scala.
ClojureScript is not Clojure.
PureScript is not Haskell.
Both languages per line have however very strong similarities and are super easy to pick up when you know the other.

PureScript is categorically not like Scala.js nor ClojureScript. Users aren’t systematically sharing code. With Scala.js and ClojureScript they most definitely are. Unlike PureScript both languages go far beyond “similarities” to deliver significant benefits for practical usage.


This topic was automatically closed 182 days after the last reply. New replies are no longer allowed.