Trying Clojure again

2020-07-25

<prev next>

I've started playing D&D again, and it's been online (for posterity, we are in the midst of the covid-19 pandemic and times are all around interesting). There are few Virtual Table Top (VTT) options, with similar feature sets.

Naturally, none of the VTTs are perfect and natually I think I can do better (somehow believing I can, in my spare time, complete a more ambitious project than my full time job).

Anyway; new project. I want a web based front end. I'm not interested in learning JavaScript (just because). I know a little Dart, but what about ClojureScript? I've used that a little and I think it's a great language. I've used a bit of Clojure too (for some school projects nigh on 7 years ago now).

What I remeber is the language being a pleasure, but error messages were inexplicably obscure[0] and installation is a pain in the neck.

Turns out the last 7 years have changed nothing as far as I can tell. It's probably not worse, but it feels worse after installing rust (rustup and the dang thing just works) or Go or Dart (although the latter two I've used in work context so a well trod workflow was laid out for me).

It seems both problems (bad exceptions and lousy install experience) are at least partly rooted in Java. Clojure uses chunks of Java for its runtime, so backtraces are natually a bit.. thick. The JDK seems to be a moving target, which naturally complicates installation. I had to roll my default Java back to version 8 to install Leiningen and now nrepl won't install and I suspect it's unhappy with the old version of the JDK, so.. nuts. It doesn't help that there are at least three package systems for Clojure (leiningen, boot, and clj) and it is not at all clear which I should be using to start out. It's also unclear if I should be using my system's packages for these things or if I should just be installing everything user-local (in general I would prefer that apt upgrade take care of everything but this doesn't seem to work well in some cases (especially node.js which seems to violently explode if you try to develop on top of system pakages)).

Anyway, blah.

[later]

Tried Boot, which worked on my laptop but not desktop. It seems like there was some old junk on my Desktop so my problem with Leiningen wasn't Leiningen per se; I purged some packages and re-installed Leiningen from apt and now I've got it working both places. So, I assume the problems I ran into are my own fault (probably I installed Leiningen at some point in the past?) but it'd be nice if the install either told me there was some conflict or was hermetic. I think Rust still compares favorably (although Python seems about the same (or maybe worse)).

[later still]

Ok. So, I found a project called luminus, which helps populate a project with handy libraries. It's been pretty useful to get me started; it builds a template and you can opt into additional libraries for it to setup for you. I've re-generated my project a few times to get the combination of stuff I think I'll need. I've just started playing with reagent, which is pretty slick. (update: follow up)

[even later]

The syntax errors really seem inexplicably bad to me. It seems that any problem loading a file is reported as a "syntax error" with a giant backtrace. Unbound symbols and dependencies which cannot be found are all reported as syntax errors. Sometimes the giant backtrace contains additional hints, but even in the CIDER output (which I believe does some filtering) it can be hard to spot those hints. You do get a line number, but it's often the line on which the toplevel form starts, not neccisarily the line where the problem occurs (this doesn't seem to be an issue with macros in particular, where the limitation would make more sense to me).

There are some questions about this on the internet, and the general response is to program incrementally so you know where your problem came from. That's... I mean OK, but errors can creap in and if I'm evaluating s-expr at a time rather than file at a time I may not catch them until multiple changes have accumulated.

I've started using clj-kondo, which seems to be a nice linter and gives finer grained error reports, but it also has false positives (e.g. it doesn't recognise core.match so reports unbound symbols in match forms).

It probably comes down to Clojure's smaller development team. I can see compiler error reports being a lower priority for experts (it's already become less of an issue as I acclimate to the language, and I imagine I'll develop an instinct for where "syntax" erros are coming from and where to look in the stack trace). This is just a place where other languages are doing a much better job (Rust again does a really nice job with this: the compiler has granular error messages that report exactly where in your code a problem was discovered).

[0]: [some days later] They may be better now. The Java related tracing is indented, so you can scan a trace and skip over all the indented lines looking for the more useful error messages. I imagine there are times when the Java stuff is actually useful, but I wonder if there's some flag to filter it out (I guess I could just stuff the whole thing through sed. I've done worse).