Erlang has a bunch of tools to help enforce determinism or at least suss out concurrency issues. For example: you can specify multiple receive statements to process your queued messages in a specific order, there is also a process manager (pman:start()) that allows you to explore concurrency related events, and not to mention Mutex Semaphores as a pattern to mitigate those issues.
There doesn't seem to be a real solution to deadlocks. I got the oreilly book in front of me and it's basically saying: be careful, but don't worry.
And I don't think erlang has a shared mutable states. In fact a google search for "erlang shared mutable state" has you as the first result.
You have ETS and Mnesia that are technically shared mutable state, and people have built Raft / Paxos / DeltaCRDT / etc. which also provide some form of it -- albeit a safe one -- but while it does exist, actually sharing the state between PIDs is a very rare thing ime. I don't have super in-depth experience in the Erlang ecosystem, so take this with a pinch -- or handful! -- of salt ofc.
ETS is isomorphic with a data table process that processes get and set (and etc) messages, but happens to be quite a bit faster.
If ETS is shared mutable state, so is a process with state that accepts changes, as chrisseaton posits. Of course, shared mutable state with clear boundaries between mutations is a lot better than shared memory where everyone can write and read things in bits and pieces.
> And I don't think erlang has a shared mutable states.
Arguably (well, of you ignore the process dictionary, which everyone seems to) Erlang lacks local mutable state, but has shared mutable state through actors.
I feel like this whole thread could stand to have people more clearly define the way they are using the term. I don't know of any "immutable" system that literally never changes or something. If Erlang is "mutable" in t sense, what system isn't?
I've seen such ideas tossed around, but I don't think I've ever seen an implementation.
> And I don't think erlang has a shared mutable states
An actor has state. It's mutable - each message can modify it. It's shared - two process working with a shared actor share that state. To me, that's shared mutable state. It causes classic race conditions.
(I know this is an unpopular opinion, and somewhat deliberately contrary and provocative, but ultimately truthful.)
While this is technically "shared state" (in the same way that a "database", or "the console/log output" is "shared state"), it's not a problem in the classical data race sense. And because you're forced to think about it in an explicit fashion, it's generally not a problem for the working programmer in the BEAM vm.
Also note that erlang is not a pure actor system. It is relatively hard to accidentally write a deadlock in erlang with OTP. In about 3 years of programming elixir I've only written a deadlock three or four times (and caught them all in tests). Even so if I had pushed it to prod, it would have timed out certain operations that would have triggered dynamic restart of the relevant processes.
two process working with a shared actor share that state
I think this is where I disagree. They may share an actor but the state of the actor belongs to the actor. To say they share it implies they can always change it independently but that's not the case. Actors don't trample on each other's internal states. For example a simple mutex semaphore pattern fixes your race condition.
> They may share an actor but the state of the actor belongs to the actor. To say they share it implies they can always change it independently but that's not the case. Actors don't trample on each other's internal states. For example a simple mutex semaphore pattern fixes your race condition.
The actor's state is shared in the sense that both processes can change it in ways that are visible to each other. The actor can control access to it, but unless the actor never changes state in response to messages (in which case why bother with actors at all?) there's still something that changes. Constrained state is still state.
There doesn't seem to be a real solution to deadlocks. I got the oreilly book in front of me and it's basically saying: be careful, but don't worry.
And I don't think erlang has a shared mutable states. In fact a google search for "erlang shared mutable state" has you as the first result.