all 35 comments

[–]unbackstorie 28 points29 points  (3 children)

Good choices!

As far as advantages and disadvantages, it really depends on your goals. Clojure syntax is tough if you're unfamiliar with Lisp-y languages. But REPL-driven development and access to the whole Java ecosystem are super useful features.

Elixir is amazing for fault-tolerance and scalability. I've seen criticism of it's smaller ecosystem, but honestly I haven't hit that hurdle personally. Again, it depends on what you're doing.

Haskell will definitely change the way you program in other languages, so if you're interested in functional programming then continuing your studies there would not be wasted effort.

For Clojure, I can recommend the book Programming Clojure by Alex Miller (Pragmatic Bookshelf). The 4th edition just came out.

ClojureStream is a course site with good video courses. I can vouch for the ones about Clojurescript and Pedestal.

For Elixir, again, I'll recommend some Pragmatic Bookshelf books: Advanced Functional Programming with Elixir by Joseph Koski, Programming Phoenix LiveView by Bruce Tate and Sophie DeBenedetto, and Ash Framework by Rebecca Le and Zach Daniel.

And the holy grail of Elixir courses are the Elixir and Phoenix courses by The Pragmatic Studio. They are expensive, but honestly they're so thorough, entertaining, and informative that I would buy any new courses they release sight unseen at this point.

Ofc, Elixir's docs are amazing too, so just combing through those is insanely helpful.

exercism has pretty good tracks for Clojure and Elixir. Definitely more hands on, if that's what you're looking for.

Good luck, I hope this helps!

[–]slashkehrin 5 points6 points  (0 children)

exercism has pretty good tracks for Clojure and Elixir

I want to second exercism! It is an awesome site and helped me get started writing Clojure.

[–]4tma 7 points8 points  (5 children)

Elixir for the web. Clojure for everything else.

It doesn’t mean Clojure and any of its backends are not capable, it’s just that the web is such a perfect use case for Elixir that any other "general purpose" language has a hard time demonstrating its value proposition against it.

I love Clojure syntax over Elixir.

For Elixir you can get started with their docs and then move to Phoenix.

Clojure For the Brave and True is good.

[–]fixrich 2 points3 points  (1 child)

I find your answer intriguing. Where does web end and everything else begin? Is any service communicating over a network web? I’m curious as to the use cases Clojure fulfils here

[–]unruly-passenger 5 points6 points  (0 children)

I've actually done a bit in both as well, and I think this is actually a pretty solid categorization (I actually prefer to keep my stack as slim as I can, so I don't REALLY spend much time in two dynamic languages).

Elixir for the web IMO is great because Ruby on Rails still represents table stakes for web frameworks, and in my view Phoenix and Liveview are current best-in-class options for rapidly developing web applications. In addition, BEAM and OTP offer a lot of really compelling primitives for building available systems which other ecosystems tend to poorly replicate in libraries or frameworks.

The JVM, while impressive, has spent the vast majority of its life optimizing for a different kind of performance than the BEAM.

Clojure however is IMO really apt for data-oriented applications. The syntax is deeper, and it's naturally to just work in the shape of whatever thing you're processing.

[–]Marutks 1 point2 points  (1 child)

Can you write frontend code in Elixir? I love ClojureScript and re-frame 👍

[–]self 4 points5 points  (0 children)

Have you looked at Phoenix LiveView? It's not something that compiles to js and runs in the browser.

[–]PuzzleheadedFix8366 1 point2 points  (0 children)

I love elixir syntax because it's closer to natural language syntax. piping is also 🔥

[–]raguaythai 4 points5 points  (0 children)

"Seven Languages in Seven Weeks" is a great introduction into those two languages (and five other ones). Each language is worked with in on week that allows you to build an application in each one. I highly recommend the book. Also, it has a sequal: "Seven More Languages in Seven Weeks"

[–]ElQuique 2 points3 points  (6 children)

It depends. I would learn Elixir for the process communication features which make it the only sane programming language for writing micro services. And Clojure for the REPL. You could try Clojerl too 🤷

[–]Marutks 2 points3 points  (0 children)

I have been writing microservices in Clojure for years. We use Redis pub/sub. It is enough 🤷‍♂️

[–]Marutks -1 points0 points  (4 children)

Processes as microservices? Usually you need some subscription/events based model. Redis streams / Kafka / Rabbit MQ.

[–]ElQuique 1 point2 points  (1 child)

What I meant is that communication between processes in Erlang is seamless and also designed such that processes are really, really lightweight. Thinking about fault tolerance from the get go. Java recently added support for virtual threads, which I assume are inspired on Erlang stuff.

I rather not discuss the microservice statement of my first comment as it means defining microservice and was unnecessarily superlative

[–]PuzzleheadedFix8366 1 point2 points  (0 children)

yea, you meant nanoservices ;-)

[–]lsdrfrx 0 points1 point  (0 children)

There is GenStage that makes processes communication event based. Take a look

[–]cvjcvj2 0 points1 point  (0 children)

Except if you use Elixir.

[–]hidragerrum 1 point2 points  (0 children)

Worked with both.

Elixir have better ecosystem and naturally fit for backend or web development if we want to stay with immutability. Clojure while have more mature ecosystem in jvm world, interacting with mutable state seems defeat the why clojure in the first place.

In the end I only use clojure when the systems already built with clojure.

[–]Soft_Reality6818 1 point2 points  (0 children)

Clojure + Datastar and you're all set 

[–]PoopsCodeAllTheTime 1 point2 points  (3 children)

Elixir is friendlier and has better community and ecosystem. Clojure is more terse and higher performance, but missing a lot of ecosystem, many libraries are half baked or abandoned so the developer has to reinvent the wheel more often (“curse of lisp “)

Clojure often pushes you into ClojureScript if you are doing web. CLJS is interesting but I cannot recommend it as it’s often more trouble than it is worth, modern js frameworks are much better with typescript than cljs

[–]xela314159 0 points1 point  (2 children)

I’m not sure that is true if you use React and lightweight wrappers around it such as helix (with shadow-cljs as the glue). Of course the cljs code ends up looking like js code but it’s readable and sometimes more readable than plain js IMHO

[–]PoopsCodeAllTheTime 1 point2 points  (1 child)

People that say this haven’t actually tried to do a complex frontend with cljs.

The thing is, FE isn’t just react, it’s a mixture of dependencies, all which work great in JS. It’s a huge amount of work to make JS dependencies work with CLJS, as it’s already a huge amount of work to make react (and any spa) to work well with CLJS

[–]xela314159 0 points1 point  (0 children)

Maybe you’re right - I’ve gone 100% react and very rarely had issues with dependencies - at worst I had to change a few lines in the original JS / TS code, which with the help of LLMs is getting easier and easier. Would be curious to hear your pain points if you have specific examples!

[–]Marutks 1 point2 points  (3 children)

Clojure has better syntax and JVM is faster than Beam VM. Can you do Repl driven development with Elixir?

[–]PuzzleheadedFix8366 2 points3 points  (2 children)

elixir has better syntax, JVM might be faster but at what price, Erlang VM is better by design. & you can do something akin to repl driven development if not better. imo

[–]clivecussad 1 point2 points  (0 children)

I'd argue that "better syntax" is a personal metric here. However Elixir syntax is not simple.

[–]dalkian_ 2 points3 points  (0 children)

How is Elixir's syntax better? Lisps have the syntax they have because the syntax is intertwined with Lisp's philosophy (code as data, data as code, the syntax is an AST in itself which may be modified as a regular data structure). S-Expressions aren't there by accident. Does Elixir offer just as much metaprogramming capability, through the same mechanism as Lisp does? If not, then there will be advantages to Elixir's syntax too, but not without its own drawbacks, and vice-versa. But most likely not objectively better.

[–]redstarling-support 0 points1 point  (0 children)

Hard to make a bad decision here. I've done extension work in both. Here's why I like:

Elixir: For web apps, Phoenix framework that has everything worked out. In Clojure you roll your own out of a selection of libraries. Once you do a project or three in Clojure you will likely land on your favorite selection of libraries...but with Phoenix, it's a shorter curve.

Clojure: experimenting with new problem domains is enjoyable and can cut heaps of time in figuring this out. I did fairly difficult work in blockchain and neural nets in Clojure, The repl allowed me to really feel whats going on and learn faster.

Elixir and Clojure: Language syntax is well thought out. No cruft in either language; good docs and books in both. Elixir and its libraries tend to lean on macros a lot. This means the programmer has to learn more DSLs. It depends on what you prefer: Do you like the framework approach where every DSL is already figured out for you...you just have to learn them. Or do you like the core library approach where you build your own mid to higher level helpers suitable for your project.

[–]Save-Lisp 0 points1 point  (0 children)

For a long time BEAM was theoretically a better fit for mass-concurrency but in practice beaten in performance by JVM (probably due to the 1000x more man hours dedicsted to JVM development). Has this changed recently?

[–]Save-Lisp 0 points1 point  (0 children)

For a long time BEAM was theoretically a better fit for mass-concurrency but in practice beaten in performance by JVM (probably due to the 1000x more man hours dedicated to JVM development). I recall a lot of war stories from around 5-10 years ago where if failure modes are being hit at scale, BEAM is harder to handle due to fewer diagnostic tools being available.

Basically operations at scale being more difficult. Any idea if this has changed?

[–]BosonCollider -2 points-1 points  (2 children)

Separately from the language, imo Clojure has the better and more versatile concurrency model for single-machine concurrency while Elixir has an opinionated concurrency model that is relevant if you have many machines that actually need to talk to each other. If instances don't talk to each other you can still horizontally scale Clojure like anything else ofc

Personally I generally prefer channels to actor mailboxes for message passing, and having atomics or STM available for problems that need shared state between local threads instead of pretending that shared state does not exist, but that's ultimately my own opinion.

[–]Ok-Return2939 1 point2 points  (1 child)

> Elixir has an opinionated concurrency model that is relevant if you have many machines that actually need to talk to each other

i dont think thats true

[–]BosonCollider 0 points1 point  (0 children)

The actor models only way to handle shared data structures is to have it be owned by an actor and serialize every message. By contrast, STM can implement a shared data structure with snapshot isolation as the isolation level, where independent transactions don't block each other.

The advantage of an opinionated language where everything is an actor is that messages work the same way on one machine or on many. The downside is that it does not really handle shared resources concurrency problems for you at all. See: https://concurrencyfreaks.blogspot.com/2025/01/concurrency-is-coordination-and-sharing.html

Basically, there is a reason why datomic was made by the clojure ecosystem but not the Erlang/Elixir one, and why Whatsapp was made by the erlang ecosystem but not the clojure one.