[Pitch #6] Actors

This proposal does model it in the language, using the same notion of isolated parameters that is used everywhere else.

It is better because it acknowledges the fundamental nature of actors, that they are synchronous internally but asynchronous externally, and naturally abstracts over different actor types. The fact that this approach falls out of the existing actor semantic model with one generalization---that "anything that conforms to Actor is an actor type"---is a strong indicator that this is the natural semantics.

In contrast, every solution proposed to try to re-use synchronous protocols for actor types is trying to paper over this fundamental nature of actors, and they immediately descend into complicated type systems. Both isolated protocol conformances and sync actor types (also see problems with sync actor types are massive complications to the type system, and we're not even sure that they're sound ones. Sometimes, the inability to express something cleanly in the type system is an indication that you're working against the nature of the language.

This is safe, and you are misunderstanding the model. Let's give DataProcessible a synchronous member:

protocol DataProcessible: Actor {
  func f()    // type of this member is (isolated Self) -> () -> Void
}

func g(a: DataProcessible, b: isolated DataProcessible) async {
  a.f() // error: a is not isolated, you have to use async
  b.f() // okay: b is isolated
  await a.f() // okay
}

The key is that the "self" parameter of any instance member in an Actor-derived protocol is isolated, just like the "self" parameter of an instance member of an actor type is isolated. Same principle, minor generalization.

I think the actor protocol vs. : Actor syntax is a distraction here. My approach is to let the instance members of protocols have isolated self parameters.

Doug

1 Like