I personally prefer Racket because of the ease with which you can use it to hack on itself. Macros are no stranger to LISPs, but Racket goes beyond by having the entire system around it built to accommodate language design and modification.
Want to use dynamic typing? Just use #lang racket. Want to use static type checking? Use #lang typed/racket. Reactive programming is there with #lang frtime. And that's before we even consider things like Scribble.
As an aside, I totally agree with you on Elixir. Erlang is wonderful for what it's built for. Elixir's choice to use Ruby syntax, however, ruins Elixir for me -- and it's not because I hate Ruby. I actually like Ruby a fair deal. Instead, it's because using Ruby syntax makes it more difficult (for me) to truly and fully think in the paradigm. Erlang/Elixir are nothing like Ruby. Making the syntax Ruby-like just obfuscates what's actually going on in the system. (I find similar issues whenever I try to program using imperative chunks in, say, F# or Scala.) Just my two cents.
That said, the JVM is a huge part of why I like Clojure. Because of the mountains of corporate code written in Java there is an insane amount of pretty high quality (if extremely object oriented) code available for it. I can find a library for basically any third party tool I'd want to use and if someone hasn't written a Clojure wrapper for it yet I can whip one up pretty quickly most of the time.
But Racket... oh, Racket. Every time I get to write Racket, I feel like it’s the past, present, and future.
I do like some of the immutable collection abstractions in Clojure, and I like that there’s always a library in Java that’ll allow me to mostly still write Clojure. But Racket is definitely my language sweet spot.
EDIT: Oh, but just getting started:
- How to Design Programs 2nd edition (new to programming or structured reasoning about programs)
- Racket Guide (new to Racket)
- Racket Docs (for reference)
The docs are pretty great, but IMO there’s an opportunity for people to blog about production use cases.
Also, I dream of something like R’s tidyverse being written for Racket... maybe by me, but ideally by someone smarter and better.
I'll check out serverracket!
The issue with dynamically typed FP is that FP is essentially about functions as mathematical objects, and there's really nothing mathematical about dynamic typing. Primarily, static types act as a proof, and because we're talking functions in the mathematical sense, you can actually reason about your program in the normal way.
Haskell is for eggheads though. What I really like is Rust, which feels like you're using Haskell and C at the same time. It's both powerfully low level and powerfully high level, and extremely pragmatic.
All that said, it sounds like you're super passionate about clojure, and I hope no one rips it out of your hands. I know what it's like to play the language wars games, and I wish you and all our fellow brethren the best of luck.
Of the languages you mention, Elixir seems to me like the closest experience to Clojure. Of this list:
"Lispiness, dynamic typing, functional programing, immutability, lean pragmatic design, and it runs on the JVM."
Only missing "Lispiness" and "runs on the JVM".
As for "Ruby-like" syntax, this sounds like people not trying Lisp because "too many parentheses".
It'd be hard to give up my precious parentheses though.
Yeah, that's the "Lispiness".
Elixir does have macros, but I still don't think any macro system is as powerful or user friendly without S-expressions.
It's kind of the last step of a language becoming just another Lisp.
Of the languages that I've enjoyed, I've spent the most time in Go. I've kind of just hitched my wagon to it, regardless of whether I like it or not.
Clojure is a locus of things I really, really like and I have no reason to change despite the recent FUD around it. Namely: Lispiness, dynamic typing, functional programing, immutability, lean pragmatic design, and it runs on the JVM. I haven't seen anything that compares to it in these regards that also has the community support that Clojure has (great projects like Leiningen, Lacinia, and so on).
I've tried Haskell but felt I was fighting the compiler due to the static typing (I hate static typing). It also felt like it was designed for eggheads and not people like me just doing a job. Scala feels like it doesn't know what it wants to be when it grows up. Elixir and Erlang are neat but I haven't had a chance to really try them out, but Elixir's choice to emulate Ruby-like syntax is unfortunate.
That said, I do have a high degree of proficiency with Python, which shares dynamic typing and kinda-functional programming with Clojure. Python was my language of choice for years before I finally gave Clojure a try, and I haven't really looked back. The poor handling of the Python 3 switch really soured me to Python.
I also did a good chunk of Go, but the static typing and syntax weirdness just killed it for me. Amusingly, Go seems to have a similar "ivory tower" approach to language design to Clojure - which indicates that type of management isn't really a problem for me.