alice

alice

What are the main benefits of Elixir compared to Clojure?

Hey,
Just curious what are the main benefits of Elixir compared to Clojure?
When is Elixir more useful than Clojure and vice versa?
Thanks.

Most Liked

dimitarvp

dimitarvp

Erlang and Elixir (and likely any BEAM language) give you:

  1. 99% transparent parallelism and concurrency. I can’t stress enough how important this is and how I spent 15 years of my career trying to emulate this trait in at least 5 other languages (and failed like everyone else who tried the same).
  2. Lag-less operation: spawn 50_000 tasks and the runtime will give them all a fair treatment for as much as the hardware allows.
  3. Pre-emptive scheduling. No single task can slow down the others.
  4. Ability to structure your software as a tree of tasks and supervisors, with the supervisors restarting tasks if they fail. The so-called fault tolerance. This is EXTREMELY underrated and people usually come looking for this in Erlang and Elixir after suffering in other ecosystems for a long time. I haven’t met a single new programmer who is able to appreciate how much of a productivity boost and a reducer of stress this feature is but oh well, what can you do.
  5. Elixir-specific: macros. Basically code generators at compile time. Another vastly underrated productivity booster.

While other 30-year old languages like OCaml are still struggling to even produce a working multithreaded runtime (hope it doesn’t take them another decade to make an actor runtime!), and others like Rust are just now laying the foundations of a solid asynchronous multicore runtime (and Go never being that impressive in that regard to begin with), Erlang has been enjoying a multicore pre-emptive runtime for 20+ years, long before mainstream multicore CPUs even existed.

Many programmers underestimate these aspects, to their peril.

Elixir is one of the secret weapons in the programming area.

60
Post #3
rvirding

rvirding

Creator of Erlang

The parentheses give you the simplest most consistent syntax. That Elixir is lacking them makes things more complicated. :wink:

33
Post #7
lucaong

lucaong

Clojure is in my opinion a wonderful language (like many LISPs), that shares quite a few things with Elixir: both are functional without being pure, both are dynamically typed but support some tooling around enforcing types, both rely on immutable data structures, both have powerful meta programming in the form of macros written in the language itself, and both are compiled into an intermediate form, making them especially powerful for long-running programs, less so for scripting.

Apart from the differences related to the JVM versus the ERTS, that others have mentioned, I would also mention some differences in the focus and practices of the community:

  • Elixir and Erlang are designed from the ground up to allow for concurrency through the actor model (Erlang processes). While it is completely possible to write concurrent software with Clojure (for example with channels), concurrency in the Elixir and Erlang world is a core value that permeates the design of the language and its libraries.

  • The Clojure community tends to promote small composable tools over frameworks. While Elixir also places a lot of value in small composable modules, its community also provides high quality frameworks like Phoenix and Ecto. This is totally subjective, but I personally like Elixir on this aspect.

At the end of the day, there is virtually nothing practical that one language can do and the other cannot, and they have many similarities, but they do have slightly different “core values”.

On the point of syntax, apart from the old jokes about parentheses, I learned to be mindful of familiarity bias: what looks strange and difficult to understand is not necessarily objectively worse or less readable. If a syntax is consistent and minimizes special exceptions (and that is certainly the case with LISP), it’s often just a matter of getting used to it. After learning and loving very different languages, I now consider “syntax looks strange to me” not a good reason for dismissing a language.

didibus

didibus

#1 Elixir is not a Lisp, Clojure is one

The parenthesis and s-expressions are actually a big part of this question, as well as the dynamism of the language compiler and the REPL driven development it brings. Those things go hand in hand, and are integral to what makes Lisp interesting.

This is also the hardest part to explain, and is almost impossible to answer to someone asking, because the importance of syntax as a means of expression and its semantic implications is a very abstract thing.

In Lisps, the code is the unambiguous tree of evaluation, it is what actually gets transformed and computed, you’ve removed a layer between you and the machine. It’s the closest syntax to pure untyped lambda calculus you’ll find.

Clojure is a Lisp, and Elixir is not. That’s a big difference.

You have to wonder, why is it every language has someone writing a Lisp syntax for it? You don’t see that happening with other syntaxes. And I wish I could explain the appeal, but it’s not easy to convey.

Like others have said, the syntax is “simple”. What that means is that the rules for how it works are very few and very clear and unambiguous. It means that you start with very few building blocks, and from those you can accomplish everything. It means that it is well structured, and thus easy to parse and manipulate, which makes it in turn easy to extend. Since it is so unambiguous, it also means it’s a great way to serialize data of any form. And because it already forms an evaluation tree, it can be manipulated and edited at the evaluation structure level, what Lisp editors refer to as “structural editing”. It also means that everything is “unambiguously scoped and self-contained”, and that makes it trivial to build a REPL around, with clearly delineated forms that can be “read” as a unit and compiled as a unit.

These properties in my opinion makes it a superior syntax in all aspects over Elixir’s, except for:

  1. It isn’t as familiar to people, and appears visually noisy
  2. As a result of #1, it is harder for newcomers to learn and appreciate
  3. As a result of #2, which means it doesn’t attract as many people to it, it tends to also limit the growth of a language and thus the number of people contributing libraries, frameworks and patches to the language
  4. It gives so much power to the programmer, that they can be tempted to go wild with it even beyond the point of what mortals should attempt

A superior syntax doesn’t mean that it will result in you writing superior programs with it. That is very much dependent on your own ability to leverage it to your needs, and your own mental model.

What it does mean is that for people who do care, and are looking for these properties that s-expressions bring, Elixir not being a Lisp and Clojure being one is a huge factor on deciding to use Clojure over Elixir. Similarly, for people that don’t care, it is a huge factor in choosing Elixir over Clojure.

#2 Elixir runs on the Beam VM, Clojure runs on the JVM

This is the second biggest differentiatior. The style of programs you can write and how you write them will be dramatically different because of the difference in those runtimes.

The BEAM is designed from the ground up to run distributed systems, that means that you cannot have two piece of code run concurrently or in parallel in ways where they share data. It also means that it doesn’t rely on the OS threads for concurrency and parallelization, implementing its own scheduler for concurrent code execution.

It also means that it’s exception handling is modeled for distributed systems, providing all the tools you need to easily add fault tolerance and resiliency to such a system, as well as giving you ways to communicate across nodes of such a system and synchronize nodes and all that.

Elixir takes advantage of all this in turn of running on the Beam VM.

The downsides of this comes at the expense of performance for non-distributed applications, single thread performance of single machine multi-threaded code. There’s always going to be overhead in exchanging data instead of sharing it straight form memory.

Another downside, but that could change in the future, is just the investment put behind each VMs, the JVM has been funded a lot more, it has thus had a lot more optimization go into it and many companies offer long term support and all that for every version of it imaginable.

Lastly, a possible downside is similarly in the popularity of the two VMs, and thus the amount of existing tooling and libraries/framework around both, it’ll tend to be till now that the JVM has more of it.

#3 Elixir is weird, Clojure is weirder

Elixir is weird, it has different ways for doing things than your typical OO imperative language. You have pattern marching, modules, actors, enumerations, streams, and all other such things, there’s a lot to learn. But in Clojure, there’s even more weird stuff to learn, metadata, transducers, multimethods, drastically different ways of doing concurrency like executor services, futures, locks, stm, agents, csp, reducers, and just in general you’ll be faced with weirder things to learn.

#4 Elixir is much closer to Erlang than Clojure is to Java

The general semantics of Elixir are much closer to those of Erlang, the host default language. That just means you’re not gonna hit your head as often from issues that comes from just how different Java is to Clojure and really how annoying in a lot of ways Java is overall.

You won’t see a lot of Clojure programmers say that Java is all that great, it does an okay job but at the cost of a lot of annoyances to a Clojure programmer.

On the other hand, Erlang itself is quite a good language, if using itself a bit of an unfamiliar syntax which can be hard to approach. And you’ll find a lot of Elixers who have quite the respect and appreciation for Erlang, not so in the case of Clojurians towards Java.

#5 Elixir has big frameworks that have made all the hard decisions for you and don’t demand you to understand a lot to get going and build apps, while Clojure expects you to know everything

Phoenix is a great example of this, how many people learn Elixir through learning Phoenix?

In Clojure, a common question is… What project should I even try to use as my first one to learn Clojure? Because there’s no obvious framework to guide you at anything, even the kind of projects you should try to build.

Clojure simply expects you to know how to build software already, and that you already have your own personal opinion of how you prefer to go about doing things, so instead of giving you frameworks with opinions and a lot of the basic done for you, it just gives you tools to let you build your own personal framework more quickly.

#6 Elixir is only Elixir, Clojure is now a whole generation of dialects

Elixir (as far as I know), is only Elixir. Clojure is now a source of inspiration for many other languages, most of which try to achieve portability back with Clojure.

This is where you have ClojureScript, a Clojure-like that is hosted on JavaScript environments, and for which code can be written that can be consumed by both Clojure and ClojureScript.

You also have ClojureCLR and MAGIC, which are both dialects of Clojure that target the .NET CLR and the Unity runtime respectedly. Code can similarly be written in a portable way across them back to Clojure.

You’ve got Babashka, which is a scripting language that is a dialect of Clojure meant to compete with Python, Perl, Bash and the likes for common scripting tasks. It too can share common code portable between itself and Clojure.

Interestingly, you also have Clojerl, which is a dialect of Clojure that runs on the BEAM VM just like Elixir. I believe there is some level of code portability back with Clojure as well. Though this one is more in alpha state I’ve heard.

And you have many more in the works, or that are more niche, like ClojureDart, a new Clojure dialect targeting Dart. You have Ferret for hard real time embedded systems.

I’m not too sure why there are so many Clojure dialects compared to Elixir, I think one reason is that Lisp heritage, it makes implementing Clojure a lot easier I believe because of the underlying simplicity. But it could also be because Clojure has more of a self-identity in its own semantics, that Elixir would find harder to re-implement itself without all that the Beam provides. Another reason might just be Elixir is newer, or that less people need an alternative to the Beam compared to the JVM :joy:

#7 Elixir startup is slow, Clojure is slower but…

Elixir startup isn’t as snappy as some might want for things like AWS Lambda, or script and CLI use cases. That said, Clojure start time are even slower. Yet since GraalVM can compile Clojure code to native binaries (something I do not know to be possible with Elixir), with a bit of extra effort Clojure can be made to start really really fast and with no required runtime to be installed to run.

#8 I am obviously biased towards Clojure

I prefer Clojure, and I use it professionally, while I only do Elixir on some of my hobby projects as a fun learning and thing to do on the weekends. With most of my hobby projects still being Clojure or a dialect of it. So keep that in mind when reading my comparison and maybe my framing of certain differences. I tried to remain factual and unbiased, but there is no such thing as truly unbiased.

Hope that helps!

gregvaughn

gregvaughn

I respect Clojure and it was a strong influence on Elixir (more than Ruby IMHO). Here’s an old post I made in a related thread where I link to a document really comparing the JVM to the BEAM. It’s a great read. All sorts of little design tradeoffs were traded in different directions.

10
Post #4

Where Next?

Popular in Questions Top

pmjoe
I have a relationship of love and hate with Elixir. Lots of things are just absolutely right, but there are some things that are kind of ...
New
sergio_101
I am VERY much an elixir newbie. I have taken one elixir course and one phoenix course on Udemy. During that course, I saw the instructor...
New
vac
Hi, I'm quite new in Elixir and I'm trying to format a string to a PEM format. I have the certificate value like MIIDBTCCAe2...... and ...
New
shahryarjb
Hello, I have map which I want to convert it to string like this: the map: %{last_name: "tavakkoli", name: "shahryar"} the string I ne...
New
Patoshizzle
After calling mix ecto.create I get this error: 17:00:32.162 [error] GenServer #PID<0.412.0> terminating ** (Postgrex.Error) FATAL...
New
Exadra37
Sometimes I want to check if the input into a function is not a blank string. My first approach: defmodule Example do def do_stuff(s...
New
beno
I will often find my self writing things similar to: case some_value do nil -> something() "" -> something() _ -> someth...
New
wernerlaude
In AR this is so simple @articles = current_user.articles How to do in Ecto? def index(conn, _params) do current_user = conn.assig...
New
siddhant3030
Hi, I have to write a raw query for one of my project. But till now I have used ecto queries and don’t have much experience writing raw ...
New
joeerl
Hello again - after a longish gap I’ve decided I really must dig into Elixir and see what’s been happening here - so I have a few questio...
New

Other popular topics Top

shahryarjb
Hello, I get Persian date from my client and convert it to normal calendar like this: def jalali_string_to_miladi_english_number(persi...
New
sorentwo
Hello! tl;dr Announcing Oban, an Ecto based job processing library with a focus on reliability and historical observability. After spen...
977 41022 311
New
openscript
Hello! Sorry for this astonishing simple question, but I’m really stuck. I try to set up the intellij-elixir plugin, but I don’t know ho...
New
axelson
This post is a wiki (feel free to hit the edit button near the bottom right of this post to add your own changes!) This post collects co...
239 45766 226
New
fireproofsocks
I’m working on defining a simple Ecto schema for a table (in PostGres), but I don’t see where I can define a column as NOT NULL. Conside...
New
minhajuddin
I have seen a lot of code which picks the first element from a list using Enum.at(0) instead of List.first. Is there a reason why people ...
New
shahryarjb
Hello, I have map which I want to convert it to string like this: the map: %{last_name: "tavakkoli", name: "shahryar"} the string I ne...
New
stefanluptak
Hello everybody, usually, I use a 29" ultra-wide monitor for VSCode which can easily accomodate explorer (files panel) + file with code ...
New
belgoros
I’m not a pro in using Regex and can’t figure out why the following behaviour happens, especially if we take into account the difference ...
New
AstonJ
by Lance Halvorsen Elixir and Phoenix are generating tremendous excitement as an unbeatable platform for building modern web application...
460 27162 124
New

We're in Beta

About us Mission Statement