Hacker News new | ask | show | jobs
by dwaite 1777 days ago
The big difference AFAIK with Erlang (other than reference types) is that Swift's model is reentrant, while Erlang's is not.

This is why `await` is such an important keywords to litter around your code - anything can happen in between when you await and when you come back, including actor message processing. You could have another invocation against your actor instance happen in tandem.

This definitely increases the learning curve, but likely still saves time later when you are fighting various deadlock conditions.

1 comments

that's exactly the part where i lost it. The code samples talking about reentrancy and its various quircks in some proposal discussions really made me wonder where the whole thing was going..

its seems to me having an async public interface with a sync internal implementation is the most straightforward architectural design for actors, but obviously they thought it was too limiting. Do you have any idea why ?

If an actor system is fully synchronous, it is much less efficient and can't be reentrant.

Actor implementations tend to be split on reentrancy. Having multiple paused in-flight invocations of the actor means that you need to have clearly understood suspension points (hence await keywords). Non-reentrant actors like in Erlang can deadlock if two actor instances are calling one another. Because of the deadlock and some inefficiency concerns, some actor systems allow you to decide reentrancy per-actor as well.

Because Swift concurrency is an upgrade on top of decades-old systems, I believe a certain amount of additional complexity was required whether it was built as reentrant or not.

It was a bit harder to find than I expected, but here is a discussion piece around the initial choice of reentrancy by default. https://github.com/ktoso/swift-evolution/commit/d55bbbd6cc1a...