Hacker News new | ask | show | jobs
by shijie 1834 days ago
I have had a completely opposite experience during the last 5+ years as full-time Elixir dev, but I can empathize with running into a few scenarios where some library wasn't implemented in Elixir, or the library you want to use is no longer supported.

If you're looking for an "every feature I will ever need to implement has a library for it" experience a la Rails or JS, you might not be happy with Elixir (although we shall see what 5 more years does to the ecosystem).

I don't have problems wrapping a service's API and creating my own library every once in a while, if it means I don't have to trade off slapping together a 5+ service behemoth just to get a good concurrent queue working. This is where Elixir/OTP shines: the hard stuff is easy.

1 comments

Can you elaborate a bit more how the hard stuff is easy?
Paralellizing data processing is trivial, it's literally 2-5 more lines of code in many scenarios.

I've tried -- and failed -- to replicate what Elixir does in this regard, in several other programming languages. Age those tries incurred hundreds of coding lines. Only Rust came close, although it's a bit verbose, but the code still did the job.

> Paralellizing data processing is trivial, it's literally 2-5 more lines of code in many scenarios. I've tried -- and failed -- to replicate what Elixir does in this regard, in several other programming languages.

Scala's parallel collections handled this cleanly. I believe they've been removed from the built in libraries (still available as a JAR though), but the idea was that you'd just add a .par call in your data processing chain and it would use a parallel collection instead of a regular sequential one.

These examples from the documentation (https://docs.scala-lang.org/overviews/parallel-collections/o...) show how to turn a regular sequential computation:

  val list = (1 to 10000).toList
  list.map(_ + 42)
Into a parallel one

  list.par.map(_ + 42)
Oftentimes, for data processing, being able to parallelize parts of the computation makes it fast enough that one does not need to go beyond a single machine. Spark's RDDs are basically a distributed version of Scala's collection library.

One of the areas where Elixir and Erlang shine is distributed applications.

For anyone who has written socket code, the ability to easily send regular Elixir data structures as messages to processes that may run locally or remotely is pretty awesome. And once you realize that you can also send closures over the network (ie. one node can send a snippet of code to another node and it'll be executed there), mind blown.

Very glad that Scala offers this!

Do you have any insight on the underlying thread pool? Can you control the size? Is it automatically determined?

Erlang/Elixir default to CPU threads but the number of parallel thread schedulers can be manually changed as well.

> What do you think about Golang's concurrency patterns?

I’d like to ask the same question about observables in JS (e.g. RxJS)

What do you think about Golang's concurrency patterns?
They are mostly okay but I find their caveats tiring to mentally keep track of.

As a fairly experienced dev I prefer the technology to slap me hard on the cheek and not make me triple check things.

But Golang's concurrency is definitely a big step up from all the naked multithreading we had to endure and groom for decades -- that is unequivocally true!

I still find Erlang/Elixir's message passing paradigm superior though. Plus every "process" there (a fiber / green thread basically) is being transparently parallelized on another CPU core without you thinking about it at all.

As a personal scoreboard:

1. Erlang/Elixir's messages.

2. OCaml's "domain" effects (mutable shared state managed by multiple threads in a safe manner).

3. Golang's channels and messages.

I'll add - the synchronous by default, typed nature of Golang creates a massive amount of bookkeeping, as well as some fault tolerance issues you can walk into trying to build a robust service. It's definitely better than handling raw threads, but Erlang/Elixir beat it hands down.
The code writes itself!