# \[Pitch #6\] Actors

**URL:** <https://forums.swift.org/t/pitch-6-actors/45519>\
**Category:** Pitches\
**Created:** [March 10, 2021, 6:43am UTC](https://forums.swift.org/t/pitch-6-actors/45519 "2021-03-10T06:43:45Z")\
**Posts on this page:** 1\
**Showing post:** 12

<div class="post-metadata">

**Author:** ![Douglas\_Gregor](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/douglas_gregor/32/1362_2.png) [@Douglas\_Gregor](https://forums.swift.org/u/Douglas_Gregor)\
**Post date:** [March 10, 2021, 9:38pm UTC](https://forums.swift.org/t/pitch-6-actors/45519/12 "2021-03-10T21:38:49Z")

</div>

> [@Chris\_Lattner3](#):
>
> After sleeping on it, I have a high level concern about your new approach for two reasons:
> 
> 1. It is basically putting the complexity into library and API world instead of modeling it in the language/type system. This is a concern to me because the library ecosystem is FAR larger than the language ecosystem, and is the bulk of the complexity that Swift programmers have to learn in practice. Given that this is fundamental to the nature of actors, it seems appropriate to model it in the language, instead of requiring protocols to get duplicated across the library ecosystem.

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

> [@Chris\_Lattner3](#):
>
> 1. The existing protocols in Swift serve a dual purpose: both composing in implementation behavior as well as providing public interface logic for types (I understand this may be regretted by a few, but it is the undebatable way Swift works and there are no proposals to change this). Breaking this duality for actors seems like it will require duplicating protocols to model this dual nature in the cases where we're composing in public behavior. This is going to drive a lot of boilerplate and `Foo` vs `FooActor` protocols patterns.
> 
> More generally, your proposal describes a new approach, but I haven't seen an argument or rationale for why you think it is _better_ than the other two approaches. Can you share your thoughts and elaborate on that?

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](https://github.com/DougGregor/swift-evolution/blob/actors/proposals/nnnn-actors.md#isolated-protocol-conformances) and [sync actor types](https://forums.swift.org/t/exploration-type-system-considerations-for-actor-proposal/44540) (also see [problems with sync actor types](https://github.com/DougGregor/swift-evolution/blob/actors/proposals/nnnn-actors.md#isolated-or-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.

> [@Chris\_Lattner3](#):
>
> I haven't had time to do a detailed read through of your new draft, but I do see a potential problem in a quick skim:
> 
> ```swift
> protocol Actor : AnyObject, Sendable { }
> protocol DataProcessible: Actor { ... }
> 
> ```
> 
> Doesn't this imply that existentials of `DataProcessible` will be `Sendable` and allow clients to poke at sync members? This isn't memory safe.

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

```swift
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.

> [@Chris\_Lattner3](#):
>
> The solution to this (which seems consistent with your approach) is to untie these protocols from the Actor protocol, and make them be "actor protocol DataProcessible". It is the actor pointers that are sendable, not the existentials of this wierd "actor protocol" thing. Your approach is to provide a "different color to protocols".

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

---

_[View the full topic](https://forums.swift.org/t/pitch-6-actors/45519)._
