To recap, one of the main Haskell designers tried to come up with a type system for Erlang but couldn't cover the inter-process communication, probably because a process which has another process' pid is allowed to send it literally any type of message.
In Elixir, you notice the dynamic typing mostly when you're defining callbacks that take MFA-style function specs, e.g. def handle_click(m, f, a) ...
Last point, you are right about Dialyzer error messages, but people are working on it right now. Look for messages in this discussion from _asummers.
That said, I suppose a Haskell designer and me have rather different expectations from a type system. I want great TypeScript/Java level tooling, catching stupid type-style bugs, and easier to understand code. Going for a fully covered, sound, type system sounds like quite a challenge indeed and I can imagine why it didn't work out.
I disagree that "The type system can't guarantee the types of what gets sent between processes" implies "a type system would be useless". Most of my code is not busy sending and receiving messages. It's just, well, regular boring single-threaded code that manipulates data, performs some side effects maybe, etc. I'd be perfectly happy with a type system that just makes me specify, at compile time, what message types a process is expecting to receive. Somebody sends something else? My problem, runtime error. That way, each process can be decently typechecked individually, the process type can just be "pid", and you can skip the entire "how do we type the actor model" problem. I'm sure I'm wrong here in some subtly detailed way, but I'm convinced that Elixir would fit a TypeScript-like type system like a glove if you just forget about typed messaging.
Does this guarantee "if it compiles, it works"? Nop. Does it allow for readable code, extremely powerful tooling and catching stupid errors? Sure thing.
Out of curiosity, have you tried Dialyzer? It sounds like almost exactly the level of static typing you're looking for (i.e. a TypeScript-like system). It's been a part of the Erlang distribution for a long time.
Most systems aren't really at the scale where the BEAM really excels. I'd still contend that they would be far better off with a good type system to make it easy to refactor and iterate as requirements change.
Apparently Typed Akka is finally starting to arrive at a good design, after a number of iterations over the years, but seems like there is still lots of interesting research to be done in distributed type systems.
> In Elixir, you notice the dynamic typing mostly when you're defining callbacks that take MFA-style function specs, e.g. def handle_click(m, f, a)
I really noticed it in the `Enum` module - so many `any`s, on simple things like `map`. Kind of ridiculous. And protocols are not type directed, so you don't get the huge win of return type polymorphism. Kind of kills lots of useful patterns :/
> Most systems aren't really at the scale where the BEAM really excels.
BEAM's concurrency model can be helpful even at small scale. Eg, suppose you have a web app where requests to one endpoint are computationally expensive (by design, or only for certain input, or because there's a bug). If you use (eg) Rails with Unicorn, you have a smallish, fixed number of processes available to serve requests. If N is 10 and you get 10 requests to that endpoint, every other request to your site is now standing in line, waiting to be served.
By contrast, Cowboy (the web server a Phoenix app would use) will spawn a new, tiny BEAM process per incoming request, and each process gets to run a fixed number of instructions before it is paused by the scheduler and goes back to the end of the line. So even on a single-core system, a few expensive requests wouldn't affect typical requests noticeably, and the effect would be gradually increasing latency as you got larger numbers of expensive requests, not a sudden and dramatic spike.
Maybe this won't matter for your site, but it's something that you don't have to worry about.
To recap, one of the main Haskell designers tried to come up with a type system for Erlang but couldn't cover the inter-process communication, probably because a process which has another process' pid is allowed to send it literally any type of message.
In Elixir, you notice the dynamic typing mostly when you're defining callbacks that take MFA-style function specs, e.g. def handle_click(m, f, a) ...
Last point, you are right about Dialyzer error messages, but people are working on it right now. Look for messages in this discussion from _asummers.