[swift-evolution] [Concurrency] Actors + Behaviors + Signals
Marc Schlichte
marc.schlichte at googlemail.com
Sun Aug 20 14:43:41 CDT 2017
Hi,
here are some high-level thoughts on extending Actors with Behaviors and Signals.
Actors + Behaviors:
The set of messages an Actor might handle at a time is defined by the current behavior which can be changed with the `become` instruction:
```
behavior B1 {
message m1()
message m2() -> Int
}
behavior B2 {
message m3(str: String)
}
actor A1: B1, B2 {
init() {
become B1
}
message m1() {
print(„m1“)
become B2
}
message m2() -> Int {
print(„m2“)
return 1
}
message m3(str: String) {
print(„m3\(str)“)
become B1
}
}
```
`behavior` is a kind of `protocol` which contains only actor functions.
BTW, to allow for some bikeshed discussions here - I propose to use `message` instead of `actor func` - like preferring `actor` to `actor class`.
Behaviors are optional - if you don’t define/adopt behaviors, all messages in an actor are part of an implicit behavior.
If a message arrives, which is not part of the current behavior, it will stay in the message queue but ignored until a supporting behavior becomes current again.
To allow the reception of another message while a message handler is currently suspended in some async call - maybe communicating with another actor - an `interleaved` modifier for messages might be introduced. These interleaved messages are not allowed to change the current behavior though.
Actors + Signals:
Like classes, which often provide reactive APIs (via `delegates`, `KVO`, `NotificationCenter`, `Observables`, …) for unsolicited events, Actors will need a way to send messages to unknown other Actors.
I thus propose the introduction of Signals:
```
actor A2 {
signal s1(val: Int)
message m1(val: Int) {
print(„m1“)
s1(val)
}
}
actor A3 {
message m1(val: Int) { … }
message m2(str: String) { … }
}
let a2 = A2()
let a3 = A3()
a2.s1.connect(to: a3.m1)
```
Signals might also support stream functions like `map`, `filter`, `throttle`, `distinctUntilChanged`, etc, to allow for reactive value transformations of signals sent by actors:
```
a2.s1.throttle(interval: 0.2).map { String($0) }.connect(to: a3.m2)
```
Cheers
Marc
More information about the swift-evolution
mailing list