I don't know of a way to express it in this pitch's design so I'll modify the design a bit to demonstrate:
/// Instead of applying a global actor attribute such as `@UIActor` an actor conforms to this protocol
/// and specifies the global actor context using an associated type
protocol GlobalActor: Actor {
associatedtype ActorContext
}
This change in the design allows me to express this:
final actor class Store<Value, Action, ActorContext>: GlobalActor { ... }
Instances of this type are bound to a global actor without knowing which global actor. As far as I can tell this is not possible with the current pitch for two reasons: you cannot constrain ActorContext
to be an @globalActor
and you cannot apply an @ActorContext
to the Store
class.
With this modification, we are also able to apply constraints on the ActorContext
of a GlobalActor
. For example, you could write code that is generic over another actor, but must have the same execution context as Self
, or a concrete known execution context such as UIActorContext
. The compiler could take advantage of this to allow synchronous access to synchronous API of actors from other actors in generic code (as long as they are constraints dot share the same ActorContext
). I don't see any way to support this in the pitch as written. Here's an example:
struct SomeGenericView<A: ObservableObject>: View
where A: GlobalActor, A.ActorContext == UIActorContext
{
@ObservedObject let actor: A
// The compiler would need to know this can only be called on main / UIActorContext.
// I'm not sure how to express that...
var body: some View {
// sync access to members of the actor made available via additional constraints
}
}