3 ms·
Message passing doesn't have to be hard to reason about at all. Each Erlang process is just that: a process that receives inputs and sends outputs. This is it
by loewenskind 16y ago
Message passing doesn't have to be hard to reason about at all. Each Erlang process is just that: a process that receives inputs and sends outputs. This is its "interface". Why would reasoning about this be any harder than reasoning about e.g. a REST service your application depends on?
The advantage, at least with Erlang is that the system can do things under the hood to make this as efficient as possible. Today, Erlang might actually run all the processes in one thread of execution and basically just share the data between threads. It can do this since the data is read only. Later on, when we have too many cores for this to be the fastest way anymore, it can do something else without a change to your code.
STM is still locking under the hood and when we're talking hundreds of cores, that little bit of locking is going to end up putting all your threads into a nice wait queue.
Further, the real reason that manual thread management is untenable is the same reason that manual memory management is untenable: composability. You can't compose functions arbitrarily when you every function has it's own expectations about who owns the data and you can't compose functions when you don't know what locking they have. I'm not sure STM solves this completely. Does it ensure that one transaction block can't depend on another in a way that causes an unresolvable deadlock? If I write a massive framework, do I need to worry about how many layers of isolation blocks I'm building up? I know they say this is supported, but what if it's 20 layers deep and the layers cross compilation boundaries?
Message passing, on the other hand (like unix processes) doesn't have these composability concerns (though personally I think futures probably have the most potential since they're the most high level).