Where is Elixir and the Actor Model heading?

For other languages Actor Model’s, the Java/.Net whatever it was called was decent, though Rust’s Actix is pretty fantastic (with all of Rust’s tasty guarantees!).

And Rust makes a great NIF. :wink:

8 Likes

I’m going to take this off in a slightly different direction. You should not be focusing on the Actor model at all. What initially drove Erlang’s design was fault tolerance. It was built in industry, not academia. Ericsson needed software that kept running in the face of errors. They only accidentally re-invented the Actor model because of that focus on fault tolerance and supervision.

The way I’d phrase an answer to your question, is that the Actor model is the best way we know how to build fault tolerant systems today, but since fault tolerance is the primary driving design choice among the BEAM community, if a better way is discovered, I would expect them to embrace it.

16 Likes

I stand corrected, sorry.

It’s just that the BEAM technically being an interpreter (of byte code and not text but still an interpreter?) I don’t feel it will ever have an edge against C, C++, Rust, Go, OCaml in raw computing muscle. I coded 8 years in Java and I have witnessed what wonders a well-written JIT can achieve… just not sure it will close the gap enough.

I will be happy to be proven wrong in the future. :slight_smile:

1 Like

What boggles my mind is that people are still looking for the “perfect programming language” that will do everything well when since (shortly after) the dawn of the world-wide-web you’ve needed a collection of fundamental technologies (HTML, CSS, JavaScript) to even put together a reasonably interactive web page (not to even mention the supporting server-side technologies). So I hardly think that the “Polyglot Programmer” is in the realm of “Jonestown kool-aid”.

Programming languages are technologies typically optimized for a specific purpose - jack-of-all-trades technologies tend to not do anything particularly well, they are just “good enough” for some people. So if you are working with anything that has a reasonably wide scope you are usually committed to working with multiple technologies and that can mean multiple (specialized) programming languages.

Now, I know that someone will say “Erlang isn’t technically an implementation of actors”. That’s fine, but it’s close enough.

That doesn’t change that you yourself may be too fixated on the Actor model (the same way an OO enthusiast may focus on objects, totally overlooking the “messages”).

The BEAM doesn’t care about the Actor model - it’s about lightweight processes and how the BEAM schedulers manage them. For me this talk expresses the spirit of the BEAM most clearly:

Lambda Days 2015 - Torben Hoffmann - Thinking like an Erlanger

The BEAM is more than a virtual machine - it’s actually more like a mini-OS - one that is smarter about how to get the most (concurrency, rather than raw power) out of the host hardware than the actual OS it is operating on.

Complaining about Elixir, Erlang or any other BEAM langauge not being good enough for all applications is almost like complaining that bash, bourne shell, zsh, etc. aren’t good enough for all applications. The concurrency support means that you can choreograph or orchestrate concurrent activities fairly easily while at the same time being able to “outsource” certain work to other tools that may be more suited for a particular task.

Now some developers don’t want to leave the “comfort and familiarity” of their preferred programming language/environment - but that is a separate issue (and an unreasonable expectation in our increasingly “connected” world).

So competing implementations of the Actor model are largely irrelevant because the real gold is with the BEAM’s schedulers (and to a certain degree “distribution” but more from a local fault tolerance perspective rather than “heterogenous” and “world-wide” distribution).

17 Likes

I can think of many “general purpose” languages that do most things reasonably well. Golang, Rust, Python, etc.

There is a competing idea, though, that you hint at. The “learn a DSL” system. Elixir could be seen as a DSL for distributed systems. And you could use 10 other DSLs for different things. Markup, Styling, etc.

I am intrigued by the vision. I’ve tinkered with Racket on-and-off for many years for that reason.

But really, I think people are looking for that performant, future-proof, general language so that they can quite simply get the most “bang for their buck”.

Why do people want to learn programming? I think generally because they want to do a lot of cool things with computers. Well, I can do more cool things with x than I can with y. y is better at some things than x, but not by a ton.

It’s like buying a swiss army knife vs a single blade. The single blade might be amazing quality, but it’s just more handy to carry the swiss army knife around in your pocket.

It took me a while to get to that metaphor ^ haha

Yep, I understand that. I just say Actors because it is what made Elixir really click for me to begin with. I think it’s natural for humans to think primarily about the endpoints than about the letters. We want to understand the zoomed-out view, I suppose.

1 Like

There is your swiss army knife right there. But people who’ve learned one of those “other” programming languages first, think it “looks funny”- so they dismiss it.
(Some racket links).

3 Likes

16 posts were merged into an existing topic: Off-topic (Go related) posts from the Elixir Actor model thread

That’s exactly what Elixir is, because among other things (concurrency, immutability, fault tolerance) it’s also faster than most (all?) popular scripting languages. Sure Elixir is slower than Golang and Rust… but it can be anywhere from 5x to 500x faster than Ruby, Javascript, PHP or Python (I mean clean Python, not the 100 metric tons of native wrappers like numpy!) – and that makes it almost a drop-in replacement for them… and for all other native languages if you don’t care about every last cent per watt.

Elixir and a few LISP dialects can all be the swiss-army knife.

Elixir indeed gives you the most bang for your buck. Not all. I think we actually agree with each other but use different terms. :slight_smile:

4 Likes

Is Elixir faster than Javascript? I’d love to see benchmarks showing that :slight_smile: (I’ve always assumed that Javascript would be the fastest dynamic language around due to all the effort done in optimizing its VMs

Off topic, but Lua is still faster than V8 (javascript) last time I checked.

2 Likes

I made some simple benchmark scripts so see how many processes I can spin up on my laptop with elixir and got 262,084 before the Erlang VM shut it down. I wrote a similar script in JS and it got up to 11,000 before crashing. This is of course just a personal experience and may be inaccurate.

I also did a simple operations in one minute script for both and elixir got 3,858,545 operations while JS got 5,845,228.

Actor library of some sort: yes; supervision tree like Erlang: simply not possible. Really, not possible–shared mutable state stands in the way.

1 Like

That’s merely a default, which can be overridden by a command-line argument, so the actual limit is more like 132,000,000 :wink:

3 Likes

Why not possible? Check for example https://akka.io/ You isolate state in actor and only pass messages / events.

What is really hard achieve in other languages is true process isolation , one process breaks can take down all virtual machine. But if you got into cloud you can achieve this is some other way like using some orchestration for example Kubernetes which will restart pod if some failure.

1 Like

I’m familiar with Akka. You can imitate Erlang-style supervision without the BEAM and the enforcement of non-sharing, you cannot replicate it. With Akka the “message” you pass often contains a reference to a mutable object which is an immediate “game over” for Erlang-style supervision & recovery. Granted, that’s considered an anti-pattern to do that, but it can be done, so as with any other potential bug, it will creep into large production systems. (Even more fun, in the case that you do that, you have to implement locking around access to such an object… One of the great joys of concurrent programming in the Erlang style is NO LOCKS.) This leads to advice like"Don’t use actors for concurrency. Instead, use actors for state and use futures for concurrency"" and questions like this (ugh!)

Also with Akka, you’re just using the regular process threads for scheduling, so an actor ties up its “scheduler” (again: ugh!) until it’s done processing the receipt of a message. Also with Akka, if you have even one point in your code where you accidentally call a regular Java IO routine instead of the special event-driven ones, the you have the possibility of blocking a scheduler–and although there are event-driven libraries for network & file I/O, guess what’s a blocking design intended to use a thread-per-call? JDBC! There are ways to mitigate this, but now you’re configuring ForkJoinPool’s and ExecutionContext’s (ugh! ugh!)

All of that is what happens when you attempt to implement the actor model on top of a runtime which was not designed with explicit support for it.

Kubernetes is not close to a substitute. It gives you something similar but only at a VASTLY coarser grain. Restarting a whole pod is no substitute for restarting a single Erlang process. Consider the common pattern of breaking out state into a process that does nothing but handle it, so that a failure of logic or processing does not lose state. Now consider both the network overhead of having those in separate pods, plus the overhead of configuring and maintaining the deployment–simply not practical to use this to replicate the fine-grained recovery you get with the BEAM. (Not to mention the 4-6 orders of magnitude increase in RAM of a Kubernetes pod as compared to an Erlang process.)

14 Likes
3 Likes

Exactly. And thanks for the link to that paper!

And, through the absence of any metaprogramming facilities when I looked last time, really bad at building abstractions. Which is something where Elixir shines. I see Golang as a useful systems level language and I’m watching Golang and Rust go at each other while I’m eating popcorn and coding my business-level applications in a language that makes sense for doing that.

9 Likes

Uh… no? It uses a GC, has no detailed memory control, etc… It would not be even remotely useful to build something like a system chip on or a kernel or so (compare to Rust or C or C++).

Even at the higher level Go takes more code than what is usual in languages while also being less safe (Interface{}'s Everywhere!).

5 Likes

I don’t think that Go lang can be called system level language as it has GC, where Rust can for sure can be called system level.

1 Like