> Akka and Erlang have been used to implement some important scalable systems
Very few, really. Maybe you can come up with a few (besides the Ericsson router), but they are a tiny, tiny minority of how we build scalable systems today, and even if some systems are built this way, it's still no evidence that using Akka or Erlang was the best technology.
> What do you recommend as a "traditional" way to implement scalable systems?
I'm not recommending anything, I'm just observing that a crushing majority of scalable systems in use today, reliably serving billions of people and billions of API calls, are built on traditional, imperative technologies (C, C++, Java, C#, JavaScript, etc...).
This past decade, these services have been supplemented by increasingly powerful threading (thread pool, fork join, work stealing, etc...) and asynchronous (coroutines, promises, futures, channels, etc...) approaches.
The actor model has so far completely failed to prove itself as an improvement over these traditional approaches.
I also happen to think the actor model is terrible to debug, deeply violates encapsulation, and often forces developers to forego static typing, but that's more of a personal opinion than an observation.
> Very few, really. Maybe you can come up with a few (besides the Ericsson router), but they are a tiny, tiny minority of how we build scalable systems today,
Yeah, it's a small fraction because it's a rare language, but it's responsible for an outsized number of highly-scalable systems: WhatsApp, several massive ad companies, several massive trading systems, several large analytics companies. Plus most of the production XMPP systems that have been used at scale.
Look, I'm not even an Erlang/Elixir programmer, but it's pretty clearly a great technology for building scalable, fault-tolerant systems.
> I also happen to think the actor model is terrible to debug, deeply violates encapsulation, and often forces developers to forego static typing, but that's more of a personal opinion than an observation.
I mostly work in statically-typed functional programming languages at work, so I'm sympathetic to this complaint. But Erlang has the concept of fail-fast and fault tolerance that make the lack of type safety not as big of a deal as it normally would be.
It's very hard to know exactly how much of WhatsApp uses Erlang (there is hardly any documentation of that besides vague public release docs), and at the end of the day, like I said, just because a system is written with a technology doesn't mean it was the best idea.
> But Erlang has the concept of fail-fast and fault tolerance that make the lack of type safety not as big of a deal as it normally would be.
That "fail fast" / "let it crash" thing that Erlang brags about has never been convincing to me. First, because you still need to implement all these supervisors yourself anyway so the complexity is still there. Second, it's an admission that because of its lack of static typing, Erlang developers are just throwing their hands in the air and try to make pass what is a fundamental flaw in the language (that you can't effectively and exhaustively catch errors) as a strength.
Besides, Erlang doesn't have the monopoly on "let it crash": plenty of languages have better ways to catch and recover from errors, either through exceptions or algebraic data types that allow the compiler to make sure you have covered all the error cases.
> First, because you still need to implement all these supervisors yourself anyway so the complexity is still there.
Have you implemented an erlang/elixir supervisor? It's not hard. It would probably take me about 60 seconds.
> Besides, Erlang doesn't have the monopoly on "let it crash": plenty of languages have better ways to catch and recover from errors, either through exceptions or algebraic data types that allow the compiler to make sure you have covered all the error cases.
Simply handling the error is not the primary reason for "let it crash". The reason for let it crash is to have the remainder of the system continue to make forward progress and with minimal disruption.
I think if anything the greatest thing about let it crash is that I can have a relatively green junior put something into prod without worrying that an uncaught error will bring down the whole system.
Very few, really. Maybe you can come up with a few (besides the Ericsson router), but they are a tiny, tiny minority of how we build scalable systems today, and even if some systems are built this way, it's still no evidence that using Akka or Erlang was the best technology.
> What do you recommend as a "traditional" way to implement scalable systems?
I'm not recommending anything, I'm just observing that a crushing majority of scalable systems in use today, reliably serving billions of people and billions of API calls, are built on traditional, imperative technologies (C, C++, Java, C#, JavaScript, etc...).
This past decade, these services have been supplemented by increasingly powerful threading (thread pool, fork join, work stealing, etc...) and asynchronous (coroutines, promises, futures, channels, etc...) approaches.
The actor model has so far completely failed to prove itself as an improvement over these traditional approaches.
I also happen to think the actor model is terrible to debug, deeply violates encapsulation, and often forces developers to forego static typing, but that's more of a personal opinion than an observation.