Clojure is fun. It’s pretty hard to write (like rust), but you actually enjoy the process (unlike rust). The syntax takes a bit getting used to with the general “method target args” approach, but it’s not too bad, just something slightly unusual.
There’s nothing like TypeScript, but guardrails allow to type check in debug builds (optionally in release, too). Those type checks can get very elaborate, way more so than in TS given they are just the same valid Clojure.
Some control flow shenanigans take a bit to reason with, especially async. I started with Clojure and quickly moved to ClosureScript (and node) just because I’m not really familiar with Java enough. Async exists in both, there are several competing solutions (just like in rust), but it’s generally not too painful. In the end I just painted everything with a thick layer of promesa, that allows to treat promises and non-promises literally the same (as if everything is available).
Building Clojure is not too exciting. The java heritage shows even with ClojureScript and it’s very much not fun to nixify this. Took me a while to figure how to pre-fetch the maven deps so I could make some sensible docker layers. Never figured how to substitute a mvn dependency with a github fork of one. The overall dependency story feels a bit rough (cargo’s awesome).
Now, the REPL thing. Oh boy. I expected some miracle in there. There’s no miracle. Clojure is just literally a REPL: you feed it a file and it evals the contents (kind of like PHP). It has namespaces for structuring things, and you can freely switch between them in the REPL. Every time you redefine the function, the already running code will reference the new code. It’s just like that live coding from old objective-c times when Xcode could push a single changed method into a running binary via gdb. It’s very solid and has great editor support (e.g. you just alt-enter on any function in VScode to “update” it), but it’s nothing that cannot be done in, e.g. ruby or even python, just way more streamlined. And it actually helps. You can start a long-running thing like a websocket, let it be and keep writing the protocol handlers, watching how they change the behavior as you eval the code.
Speaking of the editors, the code editing story is also very good as all the code is incredibly structured, being an AST of its own. I’m actually running out of keys on my keyboard trying to use it!
ClojureScript specifically allows you to just import stuff from npm. Same goes for Java and maven, I suppose, but again, not much java experience here. Calling into npm is awesome, though. You get everything you will ever need, and yet you don’t have to write JavaScript. In fact, not having to write TypeScript either is great. I wrote many, many lines of TS, and for one I enjoy something more exciting that targets V8 (not that TS is bad, but it’s just JS with a very thick sugarcoating).