# SE-0428: Resolve DistributedActor protocols

**URL:** <https://forums.swift.org/t/se-0428-resolve-distributedactor-protocols/70669>\
**Category:** Proposal Reviews\
**Created:** [March 14, 2024, 12:20am UTC](https://forums.swift.org/t/se-0428-resolve-distributedactor-protocols/70669 "2024-03-14T00:20:06Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![Jumhyn](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/jumhyn/32/3891_2.png) [@Jumhyn](https://forums.swift.org/u/Jumhyn)\
**Post date:** [March 14, 2024, 12:20am UTC](https://forums.swift.org/t/se-0428-resolve-distributedactor-protocols/70669/1 "2024-03-14T00:20:06Z")

</div>

Hello Swift community,

The review of [SE-0428: Resolve `DistributedActor` protocols](https://github.com/apple/swift-evolution/blob/main/proposals/0428-resolve-distributed-actor-protocols.md) begins now and runs until April 2nd, 2024.

Reviews are an important part of the Swift evolution process. All review feedback should be either on this forum thread or, if you would like to keep your feedback private, directly to me as the review manager via the forum messaging feature or [email](mailto:fred.kl@me.com). When contacting the review manager directly, please put "SE-0428" in the subject line.

### Try it out

Toolchains with this feature implemented are now available:

- Linux (Ubuntu 20.04): [https://download.swift.org/tmp/pull-request/72287/758/ubuntu2004/PR-ubuntu2004.tar.gz](https://download.swift.org/tmp/pull-request/72287/758/ubuntu2004/PR-ubuntu2004.tar.gz)
- macOS: [https://ci.swift.org/job/swift-PR-toolchain-macos/1165/artifact/branch-main/swift-PR-72287-1165-osx.tar.gz](https://ci.swift.org/job/swift-PR-toolchain-macos/1165/artifact/branch-main/swift-PR-72287-1165-osx.tar.gz)
- Windows: [https://ci-external.swift.org/job/swift-PR-build-toolchain-windows/1178/artifact/build/artifacts/installer.exe](https://ci-external.swift.org/job/swift-PR-build-toolchain-windows/1178/artifact/build/artifacts/installer.exe)

### What goes into a review?

The goal of the review process is to improve the proposal under review through constructive criticism and, eventually, determine the direction of Swift. When writing your review, here are some questions you might want to answer in your review:

**What is your evaluation of the proposal?**

- Is the problem being addressed significant enough to warrant a change to Swift?
- Does this proposal fit well with the feel and direction of Swift?
- If you have used other languages or libraries with a similar feature, how do you feel that this proposal compares to those?
- How much effort did you put into your review? A glance, a quick reading, or an in-depth study?

More information about the Swift evolution process is available at [https://github.com/apple/swift-evolution/blob/main/process.md](https://github.com/apple/swift-evolution/blob/main/process.md).

Thank you,

Freddy Kellison-Linn  
Review Manager

---

<div class="post-metadata">

**Author:** ![Joannis\_Orlandos](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/joannis_orlandos/32/732_2.png) [@Joannis\_Orlandos](https://forums.swift.org/u/Joannis_Orlandos)\
**Post date:** [March 19, 2024, 9:01pm UTC](https://forums.swift.org/t/se-0428-resolve-distributedactor-protocols/70669/2 "2024-03-19T21:01:59Z")

</div>

The macOS download link keeps failing right before completion.

---

<div class="post-metadata">

**Author:** ![ktoso](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/ktoso/32/44526_2.png) [@ktoso](https://forums.swift.org/u/ktoso)\
**Post date:** [March 20, 2024, 12:51am UTC](https://forums.swift.org/t/se-0428-resolve-distributedactor-protocols/70669/3 "2024-03-20T00:51:32Z")

</div>

I worked this out with @Joannis_Orlandos -- downloads just aren't great from swift-ci sadly. curl/wget with "continue" mode helps usually.

Joannis reported the macro could not be found when he tried it, so I'll investigate the built toolchain.

---

<div class="post-metadata">

**Author:** ![cal](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/cal/32/35557_2.png) [@cal](https://forums.swift.org/u/cal)\
**Post date:** [March 21, 2024, 1:46pm UTC](https://forums.swift.org/t/se-0428-resolve-distributedactor-protocols/70669/4 "2024-03-21T13:46:59Z")

</div>

Given we have `distributed actor`, it seems like the most natural spelling for a distributed protocol would be `distributed protocol` rather than `@DistributedProtocol protocol`.

I imagine there are implementation benefits for the macro approach on the compiler side, in that it lets the functionality be implemented more independently from the compiler itself. Are there other motivations behind the `@DistributedProtocol protocol` spelling?

If it's primarily an implementation design consideration, I wonder if it could make sense to have the surface spelling be `distributed protocol`, but maintain the current implementation architecture by having that syntax implicitly add an underlying `@_DistributedProtocol` macro that implements the functionality.

---

<div class="post-metadata">

**Author:** ![jaleel](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/jaleel/32/45076_2.png) [@jaleel](https://forums.swift.org/u/jaleel)\
**Post date:** [March 21, 2024, 3:44pm UTC](https://forums.swift.org/t/se-0428-resolve-distributedactor-protocols/70669/5 "2024-03-21T15:44:08Z")

</div>

> [@cal](#):
>
> Are there other motivations behind the `@DistributedProtocol protocol` spelling?

Remember reading proposal and also was wondering. Could be wrong and @ktoso would correct, but think it's just coincidence that we have `protocol` in Swift and `protocol` in networking terminology, otherwise it would have been `@DistributedProtocol trait` or `@DistributedProtocol typeclass` or whatever.

> [@ktoso](#):
>
> Joannis reported the macro could not be found when he tried it, so I'll investigate the built toolchain.

Think also faced a problem, could test on small demo with two systems when it will be ready.

---

<div class="post-metadata">

**Author:** ![wes1](https://avatars.discourse-cdn.com/v4/letter/w/848f3c/32.png) [@wes1](https://forums.swift.org/u/wes1)\
**Post date:** [March 21, 2024, 8:29pm UTC](https://forums.swift.org/t/se-0428-resolve-distributedactor-protocols/70669/6 "2024-03-21T20:29:30Z")

</div>

It's good the proposal permits something other than Codable as a SerializationRequirement.

I can imagine services where the serialization is optimized for a given (e.g., high-performance) call. Currently I think that would be modeled with a distinct actor, and all the serialization on that actor would have to follow that serialization.

i.e., Conversely, I'm not sure how it would work e.g., to have different serialization for the result handler, even if the proposal were changed to permit that.

Either way, it's unclear what kinds of serializations could be implemented: would the current scheme permit a bootstrap phase, or the opportunity to configure e.g., local-only (in-process?) channels?

I'd welcome the proposal discussing the impact on the potential for alternative serialization and proxying mechanisms, just to be sure no doors are closed unnecessarily.

---

<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 21, 2024, 9:26pm UTC](https://forums.swift.org/t/se-0428-resolve-distributedactor-protocols/70669/7 "2024-03-21T21:26:52Z")

</div>

> [@cal](#):
>
> If it's primarily an implementation design consideration, I wonder if it could make sense to have the surface spelling be `distributed protocol`, but maintain the current implementation architecture by having that syntax implicitly add an underlying `@_DistributedProtocol` macro that implements the functionality.

Specifying that the syntax `distributed protocol` expands a macro would go against some of the philosophy of the macro system, which is that macro expansions should be explicitly visible in the source (`#` or `@` for freestanding or attached, respectively).

If what you really mean is "should this be a language feature, not a macro?", I think that the macro approach is preferable because of its flexibility and the ability to inspect what it does.

Doug

---

<div class="post-metadata">

**Author:** ![ktoso](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/ktoso/32/44526_2.png) [@ktoso](https://forums.swift.org/u/ktoso)\
**Post date:** [March 22, 2024, 12:39am UTC](https://forums.swift.org/t/se-0428-resolve-distributedactor-protocols/70669/8 "2024-03-22T00:39:29Z")

</div>

Yeah `distributed protocol` is quite tempting I have to say, but as Doug explained we're able to get away with "just" macros for part of the feature and there's some benefits from being able to just expand and look at the code it produces. It is useful and "less magical" to newcomers this way -- although the way the remote calls still use some special sauce, but at least the stubs the macro creates are easily understandable this way.

It is a bit of a wrinkle that we have to annotate here, but on the other hand -- I very much expect more annotations and information to be put into the `@DistributedProtocol` like things for versioning which will be very very important.

So... in practice I think we'll have annotations like this anyway, so might already endorse it -- and then add more parameters to it, like `@DistributedProtocol(version: .v10)` etc.

---

<div class="post-metadata">

**Author:** ![ktoso](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/ktoso/32/44526_2.png) [@ktoso](https://forums.swift.org/u/ktoso)\
**Post date:** [March 22, 2024, 12:43am UTC](https://forums.swift.org/t/se-0428-resolve-distributedactor-protocols/70669/9 "2024-03-22T00:43:00Z")

</div>

> [@wes1](#):
>
> It's good the proposal permits something other than Codable as a SerializationRequirement.
> 
> I can imagine services where the serialization is optimized for a given (e.g., high-performance) call. Currently I think that would be modeled with a distinct actor, and all the serialization on that actor would have to follow that serialization.

Yeah it's since day 1 been a goal to allow various serialization mechanisms, even if today most systems use Codable.

For example, if someone wanted to have some "store the structs raw bytes in the message and just send it" one could do that if the protocol required such capability. I'm quite interested in some high performance IPC like that, but have not really worked on new serialization mechanisms so far.

This proposal doesn't change anything here from the initial distributed actor design tbh, distributed methods can use some specific serialization mechanism -- whatever that might be.

> [@wes1](#):
>
> Either way, it's unclear what kinds of serializations could be implemented: would the current scheme permit a bootstrap phase, or the opportunity to configure e.g., local-only (in-process?) channels?

Do note though that the serialization is bound to a specific actor system -- otherwise our typesafety inside the remoteCall and encoder/decoder would go out the window -- so it isn't per-actor, but per-actor system what serialization you choose to use. I'm not sure what you mean with the phases; since the requirement is a static property, it cannot change depending on time or situation where the actor system is used.

In process actors (i.e. distributed "known to be local" actors) simply do not serialize their messages and it is plain method calls. It is interesting to be able to force serialization on local boundaries for testing purposes but we don't do so today.

It is somewhat possible to make even more generic systems by introducing some "common serialization protocol" but we don't have this yet -- I think we could explore this once we had some good bytes types in the standard library, but today we don't have such common protocol.

---

<div class="post-metadata">

**Author:** ![stevapple](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/stevapple/32/31979_2.png) [@stevapple](https://forums.swift.org/u/stevapple)\
**Post date:** [March 22, 2024, 12:43am UTC](https://forums.swift.org/t/se-0428-resolve-distributedactor-protocols/70669/10 "2024-03-22T00:43:05Z")

</div>

> [@Douglas\_Gregor](#):
>
> Specifying that the syntax `distributed protocol` expands a macro would go against some of the philosophy of the macro system, which is that macro expansions should be explicitly visible in the source (`#` or `@` for freestanding or attached, respectively).
> 
> If what you really mean is "should this be a language feature, not a macro?", I think that the macro approach is preferable because of its flexibility and the ability to inspect what it does.

IMHO the `DistributedProtocol` is a language feature that requires not only a macro  
to function. The existing `distributed actor` works much the same and also generates boilerplate code under the hood. There’s no harm to align the syntax and, since the `DistributedProtocol` is something that’s used explicitly with `distributed actor` and `distributed func`, we’d better not confuse it with other macros even if they behave alike.

---

<div class="post-metadata">

**Author:** ![ktoso](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/ktoso/32/44526_2.png) [@ktoso](https://forums.swift.org/u/ktoso)\
**Post date:** [March 22, 2024, 12:43am UTC](https://forums.swift.org/t/se-0428-resolve-distributedactor-protocols/70669/11 "2024-03-22T00:43:29Z")

</div>

Separately I'm trying to look into what's up with the macro not being found in the nightly toolchain actually -- I'll report back about this.

---

<div class="post-metadata">

**Author:** ![stevapple](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/stevapple/32/31979_2.png) [@stevapple](https://forums.swift.org/u/stevapple)\
**Post date:** [March 22, 2024, 1:03am UTC](https://forums.swift.org/t/se-0428-resolve-distributedactor-protocols/70669/12 "2024-03-22T01:03:01Z")

</div>

I’d like to quote the following paragraph from the [Vision for Macros](https://github.com/apple/swift-evolution/blob/main/visions/macros.md):

> [@](#):
>
> ### When is a language feature better than a macro?
> 
> As noted above, a macro system has the potential to replace large parts of existing Swift language features, and enable many new ones. But a macro system is not necessarily a good replacement for a special-built feature:
> 
> - A special-built feature might benefit from custom ABI rules.
> - ……
> - A special-built feature might have capabilities that we need to deny to macros, lest the mere possibility of a macro applying incur massive compile-time costs.

Although the `DistributedProtocol` macro can provide the syntax for such functionality, this feature is indeed a language feature that **requires specific ABI, instead of pure syntactic sugar**. Eliding the fact is, in some way, harmful for language users, providing wrong signals that such language feature is achievable purely by the macro system.

This means we should, at least, make it `@DistributedProtocol distributed protocol` to distinguish from regular protocols. Since we may not want users to craft a `distributed protocol` without the `DistributedProtocol` macro, eliminating `@DistributedProtocol` and making it the default behavior is a boost for both clarity, simplicity and accuracy.

---

<div class="post-metadata">

**Author:** ![Joannis\_Orlandos](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/joannis_orlandos/32/732_2.png) [@Joannis\_Orlandos](https://forums.swift.org/u/Joannis_Orlandos)\
**Post date:** [March 24, 2024, 9:09am UTC](https://forums.swift.org/t/se-0428-resolve-distributedactor-protocols/70669/13 "2024-03-24T09:09:58Z")

</div>

I'm really eager to see this being introduced, but how does the unavailability of a working toolchain affect the duration of this review?

---

<div class="post-metadata">

**Author:** ![Joannis\_Orlandos](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/joannis_orlandos/32/732_2.png) [@Joannis\_Orlandos](https://forums.swift.org/u/Joannis_Orlandos)\
**Post date:** [March 25, 2024, 7:49am UTC](https://forums.swift.org/t/se-0428-resolve-distributedactor-protocols/70669/14 "2024-03-25T07:49:31Z")

</div>

I think this is a brilliant addition that solves some real pain points in my limited experience using distributed actors. I've read the proposal fully, and think it's a great way to address this, since macros can be expanded to understand the 'magic' that's happening.

I've done peer-to-peer networking before, and think that this would really change the complexity of writing those systems.

The only thing I miss is that I haven't been able to dive into code yet, with the try-out toolchain not working correctly.

---

<div class="post-metadata">

**Author:** ![ktoso](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/ktoso/32/44526_2.png) [@ktoso](https://forums.swift.org/u/ktoso)\
**Post date:** [March 28, 2024, 10:34am UTC](https://forums.swift.org/t/se-0428-resolve-distributedactor-protocols/70669/15 "2024-03-28T10:34:21Z")

</div>

Thanks for your input and efforts to verify the feature @Joannis_Orlandos!

I was looking into why the macro wasn't found properly, and long story short: There were general issues with compatibility of custom toolchains where they were looking for macros nowadays. @rintaro did a fix ([here](https://github.com/apple/swift/pull/72629)).

You can download this toolchain for macOS: [[Pull Request] Swift Build Toolchain - macOS #1201 [Jenkins]](https://ci.swift.org/job/swift-PR-toolchain-macos/1201/) (and subsequent ones which contain Rintaro's fix), but you'll have to manually provide the paths to look for macros as follows in Xcode:

 ![Screenshot 2024-03-28 at 19.19.27](https://global.discourse-cdn.com/swift/original/3X/e/a/ea957645c7780f18fcd75dc0ef3c075efc3ca842.png)

Effectively you need to pass: `-Xfrontend -load-plugin-library -Xfrontend /Library/Developer/Toolchains/swift-PR-72629-1201.xctoolchain//usr/lib/swift/host/plugins/libSwiftMacros.dylib`

You'll still need an actor system that is able to resolve and call things on protocols, but this generally should not take much work to adopt -- as all the logic in `remoteCall` is really going to be the same.

---

<div class="post-metadata">

**Author:** ![Jumhyn](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/jumhyn/32/3891_2.png) [@Jumhyn](https://forums.swift.org/u/Jumhyn)\
**Post date:** [March 28, 2024, 4:30pm UTC](https://forums.swift.org/t/se-0428-resolve-distributedactor-protocols/70669/16 "2024-03-28T16:30:55Z")

</div>

Since the entirety of the review period passed without a functional toolchain, we'll also extend the review through April 2 so that any community members who wish to try the feature out have a chance to.

---

<div class="post-metadata">

**Author:** ![jaleel](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/jaleel/32/45076_2.png) [@jaleel](https://forums.swift.org/u/jaleel)\
**Post date:** [April 4, 2024, 3:47pm UTC](https://forums.swift.org/t/se-0428-resolve-distributedactor-protocols/70669/17 "2024-04-04T15:47:24Z")

</div>

Finally checked implementation, played with different setup—1) same system, but different instances of it; 2) two separate systems. All working fine, definitely see ways where this could be very helpful. At least will play myself creating some client-server communication.

As a consumer myself, think macro makes sense—all the building blocks for distributed actors is already there, and this one is something on top and niche, would prefer it will do some _magic_ for me so I can focus on building distributed systems itself more.

Looking forward for it to be approved and merged!

Here a small example, like how clean and easy it is **to use** those protocol:

 ![Screenshot 2024-04-04 at 17.38.39](https://global.discourse-cdn.com/swift/original/3X/3/d/3d37ed9bb02bcb9b044c28f5b3a9d73860762522.jpeg)

---

<div class="post-metadata">

**Author:** ![ktoso](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/ktoso/32/44526_2.png) [@ktoso](https://forums.swift.org/u/ktoso)\
**Post date:** [April 4, 2024, 10:11pm UTC](https://forums.swift.org/t/se-0428-resolve-distributedactor-protocols/70669/18 "2024-04-04T22:11:48Z")

</div>

Awesome, thank for trying it out @jaleel 🙂

---

<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:** [April 4, 2024, 11:06pm UTC](https://forums.swift.org/t/se-0428-resolve-distributedactor-protocols/70669/19 "2024-04-04T23:06:13Z")

</div>

> [@cal](#):
>
> Given we have `distributed actor`, it seems like the most natural spelling for a distributed protocol would be `distributed protocol` rather than `@DistributedProtocol protocol`.

I've been thinking about this more, and I realized that the problem for me is that `@DistributedProtocol` is the wrong name. Everything about the design feels right, but the name doesn't reflect what it's doing.

The language already has "distributed" protocols. They're protocols that refine `DistributedActor` and have `distributed` functions in them. Something like this (from the proposal) is already a "distributed protocol":

```swift
protocol DistributedAsyncSequence<Element>: DistributedActor 
    where ActorSystem: DistributedActorSystem<any Codable> {
  associatedtype Element: Sendable & Codable
      
  distributed func exampleNextElement() async throws -> Element? { ... }
}

```

and distributed actor types can conform to it. The language handles distributed actor isolation as part of its semantics, and provides detail to the runtime to manage the distributed actor.

Adding `@DistributedProtocol` to this protocol isn't making it a distributed protocol, because it already was one. The attribute is creating the client stub type that lets you get a remote instance of a `DistributedAsyncSequence` without having any access to that concrete type. That's what this macro name needs to capture---the extra functionality you get for adding the attribute. Perhaps something like `@RemoteStubs` or `@ClientStubs` or `@RemoteClient` would capture what it's doing.

Doug

---

<div class="post-metadata">

**Author:** ![ktoso](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/ktoso/32/44526_2.png) [@ktoso](https://forums.swift.org/u/ktoso)\
**Post date:** [April 5, 2024, 12:07am UTC](https://forums.swift.org/t/se-0428-resolve-distributedactor-protocols/70669/20 "2024-04-05T00:07:02Z")

</div>

Yeah that's a fair point, since we're not making `distributed protocol` do the thing, it might be worth exploring rather what this macro really gives us.

There's a bunch of words which I really want to avoid, for example "remote" never should show up in sources really, because we always either have known-local or "could be remote, we don't know" so `RemoteClient` is kind of true, that's the primary use case of these, but one can still use these with local values. Client and Stubs words I try to avoid in general because we're trying to have developers not think too much about stubs etc, just focus on the language and actors hm... I very much see the point that the current name isn't great though.

When we look at it from that angle, it is "it enables resolve() on this protocol" which isn't possible without this macro. All such "extends capabilities" things tend to be called "-able" in Swift, so there's actually a word we can use here:

Since this macro enables using resolve() on protocols like this, it is **`@Resolvable`** -- i.e. it is a `protocol` i can `resolve()`. All concrete distributed actor types are "resovable" in the sense that `MyActor.resolve()` exits, and this `@Resolvable`/`@Distributed.Resolvable` really adds the `$MyProtocol.resolve()`.

I'd be quite happy with that, and I think it'll grow well in the future when we have to add "stable names" or other metadata to the macro, like `@Resolvable(stableName: "OldProtocolNameForWireCompatReasons")` etc (not designed yet, but I'm sure we'll have to at some point).

What do people think about that?

[Next page](https://forums.swift.org/t/se-0428-resolve-distributedactor-protocols/70669.md?page=2)
