SE-0313: Improved control over actor isolation

The closure is "in the actor code". It's the unnamed-function equivalent to defining a method on the actor, no more and no less.

The primary motivation for isolated parameters in this proposal is to allow us to generalize from a method on an actor:

actor A {
  var counter = 0

  func inc() { counter += 1 }
}

to being able to write a free function with the same capabilities:

func inc(a: isolated A) {
  a.counter += 1
}

This feature we're discussing lets you generalize from a method on an actor to a closure that's defined within the actor.

It's independent of the actor reentrancy model. [isolated self] on a closure is no less explicit than calling an actor method from that closure.

The problem with the last line isn't about Sendable at all: it's about two isolated parameters in the same call being fulfilled by different actor arguments, so there is no single executor that we can jump to.

Let's step back slightly, because the statement "isolated actor references aren't Sendable" isn't a well-formed one to make. Types are Sendable or non-Sendable, values cannot be Sendable or non-Sendable because values don't conform to protocols. Types conform to protocols.

The argument for allowing multiple isolated parameters came from here:

  • "Therefore, we prohibit the definition of a function with more than one isolated parameter:" --> Why? This can be narrowly useful (e.g. unsafe casts when two actor instances are known to be on the same executor) and there is no reason to ban it. Why exclude a (narrowly useful) valid case and add the compiler complexity? I don't see any safety benefit to this.

I don't believe we've seen a use case for this that doesn't require unsafe casts. We've removed several other "unsafe" features (e.g., nonisolated(unsafe)) that had stronger use cases, based on the principle that we want to start with the safe model and learn more before we add unsafe things.

The argument that it is less complex to allow multiple isolated parameters than it is to prohibit them hasn't held up, as this discussion has repeatedly shown.

Multiple isolated parameters should be removed from this proposal. They can be added back when there is a way to safely indicate that various different actor instances share the same executor. Then, they'll be worth the complexity they add.

Doug

9 Likes