Perhaps some of the blame belongs on the creators of Erlang for kind of jumping on the "actor" (and later, "OOP") bandwagons as marketing? to try to make Erlang less scary.
Perhaps some of the blame belongs on the creators of Erlang for kind of jumping on the "actor" (and later, "OOP") bandwagons as marketing? to try to make Erlang less scary.
Perhaps we have different ideas of what an "actor system" is though.
> An actor is a computational entity that, in response to a message it receives, can concurrently:
send a finite number of messages to other actors;
create a finite number of new actors;
designate the behavior to be used for the next message it receives.
> There is no assumed sequence to the above actions and they could be carried out in parallel.All above are true of Erlang except intra-actor concurrency. Even the last bullet on designating behaviour: An Erlang process (actor equivalent) can decide to use a different function when receiving the next message. It just can't pipeline handling messages.
So Erlang isn't that far removed from the Actor model in its behaviour, even if it wasn't designed as an Actor system in the first place. One might say actors are an (approximate) emergent property of Erlang rather than an intentionally designed one.
Slightly off-topic but the only system I've used that was designed & built from the outset as an actor system is Rosette [1]. It was a really interesting project, and does support pipelining, but has been dormant for more than a decade.
[0]: https://en.wikipedia.org/wiki/Actor_model#Fundamental_concep...
[1]: https://github.com/leithaus/Rosette
--
EDIT: clarified that Rosette is the only system I've used that was explicitly based on the Actor model from the outset.
I think that is the key insight of actor-systems.
Actors don't have state. But they can calculate their replacement based on their immutable data. Thus the way an actor at a given address evolves is described by the functions that calculate the successor actors.
Thus you get Pure Functional Programming implemented on top of a fabric of distributed evolving entities. You can understand the behavior and evolution of such a system as a composition of function-calls, where functions always produce the same result for the same arguments.
Point is all of these deviations from actor system were choices made by the Erlang team in the name of pragmatism. They all exist because there was a use case and the first teams using Erlang needed them for something real; that Erlang is not an actor system is important, because it's a highly pragmatic system -- not one that is based in theory.
Ets tables are observationally equivalent to an Erlang process per table and sending it a message for each function call. It's not actually implemented that way, but I don't think that is grounds to disqualify it. I don't remember enough details about the naming process, but I think that might be similar; you could send a message to a naming process to set and lookup the names (although you'd have a bit of trouble finding out what the process id of the naming process is, wouldn't you?), it's just not very pragmatic.
Nifs certainly have the potential to break the model of course. I'd think selective receive should be fine too, it's equivalent to reading (or peeking) and saving messages until a matching message is received, processing that message, then processing future messages from the saved queue. It's just implemented in a more pragmatic way.
If immutability is important, then the process dictionary means Erlang doesn't qualify, but again, it's pragmatic.
I'd rather have a pragmatic almost actor system than a dogmatic Actor system that's hard to use.