So, we have been thinking about distributed actors and have a pretty solid idea of a workable model (with a pull request that implements them). I'll lean on that for my answers.
It can be part of the handle, yes. However, in the distributed case, that might not be desirable, because creating a remote proxy for an actor then requires ping-ponging with the machine that has the real actor, so you can replicate the extra information.
Whatever state makes up the identity has to be immutable and replicated, yes. In an indirect or distributed actor case, it's something more than the address of the local object. In the pull request I referenced earlier, identity is the (network) address of the actor + the transport used to talk to it.
I don't understand this last bit about nonisolated
being misleading. If something is part of the identity, you're going to need to be able to access it synchronously (hence, nonisolated
) and for the distributed case, you also need it to be replicated so it's available on a remote proxy for the actor.
We're getting a bit far afield of nonisolated let
, so it's probably best to go to another thread to dig further into distributed (or indirect) actors. We were planning on starting a discussion of distributed actors in a couple of weeks, once more of the non-distributed actors dust settles.
Hmm. Whether isolated is handled as a value-directed notion or a type-directed one should be orthogonal to nonisolated
. Either way, a nonisolated
method in an actor will alter some aspect of its self
parameter, making it either non-isolated
(in the value-directed design) or making it @async
(in the type-directed design).
Your description of the semantics of the type-directed approach is correct. However, your second displayAccount
is not equivalent to the example I used. The type-directed equivalent to the example I used is:
func displayAccount(account: @async BankAccount) {
print("Account #\(account.accountNumber) owned by \(account.owners.joined(separator: ", "))")
}
The value-directed equivalent to your @sync
version is this:
func displayAccount(account: isolated BankAccount) {
// Same synchronous accessing to BackAccount actors
}
There are certainly differences between the type-directed and value-directed approaches, and we should continue to discuss those over in the review of SE-0313, but they should not have any impact on nonisolated
.
Actually the issue raised in this proposal convinced me that the type-directed approach (
@sync MyActor
and@async MyActor
) is a better way to solve those issues related to actor isolation, because we use the type system to handle the cases in a uniformed way instead of creating complex syntax rules just for fixing holes.
Based on the above, I think you're misunderstanding the differences between the approaches. There are definitely differences to discuss, but both approaches can model what you're discussing quite directly.
Was it ever considered to default all actor members to nonisolated, requiring an explicit
isolated
to all actor storedvar
properties and isolated functions? I couldn't quickly find it mentioned in the actors proposal at least.
We haven't seriously considered it, no. Outside of nonisolated let
, use of nonisolated
in actors is actually quite rare. That's part of the reason I'm making this correct proposal, because (if you put nonisolated let
aside) you can make great use of actors without having to learn about nonisolated
for quite a while. If we switch the polarity like you mention, there will be a lot of isolated
and relatively few things in an actor that aren't labeled as isolated
.
Doug