Standard ReactiveSteam definitions for Swift

Some thoughts as a programmer who has written an atypical reactive programming library...

You're providing protocols that strongly imply ReactiveX semantics.

Some libraries (like my own CwlSignal) look a little like ReactiveX (in that CwlSignal implements all of the ReactiveX operators) but have some quite different semantics during graph construction and during other lifecycle events. For example, CwlSignal doesn't have public Subscriber concept (responsibilities are split between the private `SignalHandler` and the `SignalSender` interface) and while the core `Signal` class is a Publisher-like concept, it is single-use which would make it a very weird implementation of this `Publisher` protocol.

These differences can make protocols for interoperability a bit of a loaded shotgun. Joining two arbitrary libraries together is likely to cause problems when the libraries have different expectations.

In some respects, it would be better to have a single, standard, concrete implementation of a class that takes an event stream input and emits an event stream. This is sometimes called a PublishSubject. A generalized PublishSubject could act as the glue between different libraries on the input and output sides. That way, the semantics of the interoperability point are fixed and each library need only ensure they support the interoperability point, rather than the semantics of every other library that could be on the other side of a protocol.

To me, I feel like this would best be implemented as part of Actor model concurrency – taking inputs and emitting outputs is fundamentally what Actors *do*.

As for naming... I would *not* recommend using `Flow` it is far too generic, has been used in very different contexts and doesn't match terminology in the field. It's fine for a library to break with common terminology for its own purposes but an interoperability interface must use the established terminology. `Publisher` and `Subscriber` are fairly clear in context but can mean very different things *outside* of reactive programming. `Observable` and `Observer` are clearer but again, the `Observer` pattern in general programming is not the same as a reactive programming `Observer` so putting it in the Swift standard library would annoy some people. On an aesthetic note, I've always found `Observer` and `Observable` difficult to read – they are similar enough that I confuse inputs and outputs when I'm tired. This is one of the reasons these terms do not appear in my library.

My personal vote is that this topic simply can't be addressed by the standard library at this point. This is something where interoperability with Swift's Actor Model should be a primary concern and until it's done, any action now is only likely to be a headache later.

Cheers,
Matt Gallagher.

To me, I feel like this would best be implemented as part of Actor model concurrency – taking inputs and emitting outputs is fundamentally what Actors *do*.

Yes, I think some form of ‘reactive stream’ could be a prerequisite for the Actor model (an not the other way around).

As for naming... I would *not* recommend using `Flow` it is far too generic, has been used in very different contexts and doesn't match terminology in the field.

On the contrary, it’s not overloaded at all.
It is used in related concepts like DataFlow, ‘flow-based’ programming, etc.

Also, from the dictionary:

flow, noun
a steady, continuous stream or supply of something.

sounds like a great synonym for the (reserved?) stream name.

My personal vote is that this topic simply can't be addressed by the standard library at this point. This is something where interoperability with Swift's Actor Model should be a primary concern and until it's done, any action now is only likely to be a headache later.

I think this is a central concept that among other things is useful in concurrency. It should be tackled sooner rather than later.

-g.

I hope we come up with some genuine ideas for ReactiveStreams on Swift.

For example instead of onNext()/onError() we could have a single method which takes a Result Monad. ARC memory management might require Swift specific solutions too.

Also on the mindset: Often I see my Android colleagues using Observables to wait for the completion of asynchronous requests. But I think these control flow scenarios are better handled by async/await instead.

Reactive should be used when a component (class / actor) wants to make an unsolicited 'upcall'. As such it is firstly a modern variant of KVO/NotificatonCenter/Delegates/target-action etc. with the additional ability to transform / combine / schedule signals on the way from the signal producers to the signal consumers (signal stream processing).

As KVO/Delegates probably won't work correctly for Actors (because of execution context discrepancy), a reactive replacement working well with Actors is definitely needed.

It would be great if a Swift reactive library would allow us to design ViewModels (cf MVVM) as Actors and support 2 way bindings to the UI.

Cheers
Marc

Ursprüngliche Nachricht

···

Von: swift-evolution@swift.org
Gesendet: 24. September 2017 4:36 vorm.
An: swift-evolution@swift.org
Antworten: mattxg@gmail.com
Betreff: Re: [swift-evolution] Standard ReactiveSteam definitions for Swift

Some thoughts as a programmer who has written an atypical reactive programming library...

You're providing protocols that strongly imply ReactiveX semantics.

Some libraries (like my own CwlSignal) look a little like ReactiveX (in that CwlSignal implements all of the ReactiveX operators) but have some quite different semantics during graph construction and during other lifecycle events. For example, CwlSignal doesn't have public Subscriber concept (responsibilities are split between the private `SignalHandler` and the `SignalSender` interface) and while the core `Signal` class is a Publisher-like concept, it is single-use which would make it a very weird implementation of this `Publisher` protocol.

These differences can make protocols for interoperability a bit of a loaded shotgun. Joining two arbitrary libraries together is likely to cause problems when the libraries have different expectations.

In some respects, it would be better to have a single, standard, concrete implementation of a class that takes an event stream input and emits an event stream. This is sometimes called a PublishSubject. A generalized PublishSubject could act as the glue between different libraries on the input and output sides. That way, the semantics of the interoperability point are fixed and each library need only ensure they support the interoperability point, rather than the semantics of every other library that could be on the other side of a protocol.

To me, I feel like this would best be implemented as part of Actor model concurrency – taking inputs and emitting outputs is fundamentally what Actors *do*.

As for naming... I would *not* recommend using `Flow` it is far too generic, has been used in very different contexts and doesn't match terminology in the field. It's fine for a library to break with common terminology for its own purposes but an interoperability interface must use the established terminology. `Publisher` and `Subscriber` are fairly clear in context but can mean very different things *outside* of reactive programming. `Observable` and `Observer` are clearer but again, the `Observer` pattern in general programming is not the same as a reactive programming `Observer` so putting it in the Swift standard library would annoy some people. On an aesthetic note, I've always found `Observer` and `Observable` difficult to read – they are similar enough that I confuse inputs and outputs when I'm tired. This is one of the reasons these terms do not appear in my library.

My personal vote is that this topic simply can't be addressed by the standard library at this point. This is something where interoperability with Swift's Actor Model should be a primary concern and until it's done, any action now is only likely to be a headache later.

Cheers,
Matt Gallagher.
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

Comments in-line below.

Some thoughts as a programmer who has written an atypical reactive
programming library...

You're providing protocols that strongly imply ReactiveX semantics.

ReactiveX can be built upon Reactive Streams, e.g. RxJava 2.0., but the
idea of Reactive Streams is that the protocol is so low level you don’t
interact directly with them. They seem compatible with many different
styles including actors, e.g. Akka (the Akka people destined Reactive
Streams I think). Reactive Streams are very actor like with one way
communication links that transfer a copy of single items/errors or no
items/error (pure messages).

Some libraries (like my own CwlSignal) look a little like ReactiveX (in
that CwlSignal implements all of the ReactiveX operators) but have some
quite different semantics during graph construction and during other
lifecycle events. For example, CwlSignal doesn't have public Subscriber
concept (responsibilities are split between the private `SignalHandler` and
the `SignalSender` interface) and while the core `Signal` class is a
Publisher-like concept, it is single-use which would make it a very weird
implementation of this `Publisher` protocol.

Nothing in the Reactive Stream specification to prevent single use
Publishers, Subscribers, or Processors. The Reactive Stream specification
only talks about the communication and error reporting. As long as your
library has the concept of a subscription of some form you can probably
write translators to the 3 protocols.

These differences can make protocols for interoperability a bit of a
loaded shotgun. Joining two arbitrary libraries together is likely to cause
problems when the libraries have different expectations.

Seems to work OK in the Java world, people use Akka and RxJava together.

In some respects, it would be better to have a single, standard, concrete
implementation of a class that takes an event stream input and emits an
event stream. This is sometimes called a PublishSubject. A generalized
PublishSubject could act as the glue between different libraries on the
input and output sides. That way, the semantics of the interoperability
point are fixed and each library need only ensure they support the
interoperability point, rather than the semantics of every other library
that could be on the other side of a protocol.

This is what Reactive Streams are. They just tell you how to hook things
up, how to ask for items, how to report errors, and how to finish with a
connection. They do not dictate the semantics at the other end. For example
your translator could throw fatal exception on an error if your library
didn’t report errors or wrap the error in a Result type if it handled error
in a functional way.

To me, I feel like this would best be implemented as part of Actor model
concurrency – taking inputs and emitting outputs is fundamentally what
Actors *do*.

As I have said they are very actor like and I think it was the Akka people
who came up with the specification therefore I am not sure you are locking
anything out. If the Swift actor model can’t interact with something as
simple as Reactive Streams it will not interact with anything other than
other Swift Actors, which would be very limiting. For example you would
expect the Swift actors to interact with GCD, perhaps via suitable
wrappers.

As for naming... I would *not* recommend using `Flow` it is far too
generic, has been used in very different contexts and doesn't match
terminology in the field. It's fine for a library to break with common
terminology for its own purposes but an interoperability interface must use
the established terminology. `Publisher` and `Subscriber` are fairly clear
in context but can mean very different things *outside* of reactive
programming. `Observable` and `Observer` are clearer but again, the
`Observer` pattern in general programming is not the same as a reactive
programming `Observer` so putting it in the Swift standard library would
annoy some people. On an aesthetic note, I've always found `Observer` and
`Observable` difficult to read – they are similar enough that I confuse
inputs and outputs when I'm tired. This is one of the reasons these terms
do not appear in my library.

My personal vote is that this topic simply can't be addressed by the
standard library at this point. This is something where interoperability
with Swift's Actor Model should be a primary concern and until it's done,
any action now is only likely to be a headache later.

I would prefer to move forward more quickly, I don’t think there is much
risk since the specification is so low level and flexible. The whitpaper
from Chris Lattner also mentions that it would be desirable for any Actor
system in Swift to be compatible with Reactive Streams, so why not start
now.

···

On Sun, 24 Sep 2017 at 12:36 pm, Matt Gallagher via swift-evolution < swift-evolution@swift.org> wrote:

Cheers,
Matt Gallagher.
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

--
-- Howard.

I hope we come up with some genuine ideas for ReactiveStreams on Swift.

For example instead of onNext()/onError() we could have a single method which takes a Result Monad. ARC memory management might require Swift specific solutions too.

Also on the mindset: Often I see my Android colleagues using Observables to wait for the completion of asynchronous requests. But I think these control flow scenarios are better handled by async/await instead.

Reactive should be used when a component (class / actor) wants to make an unsolicited 'upcall'. As such it is firstly a modern variant of KVO/NotificatonCenter/Delegates/target-action etc. with the additional ability to transform / combine / schedule signals on the way from the signal producers to the signal consumers (signal stream processing).

As KVO/Delegates probably won't work correctly for Actors (because of execution context discrepancy), a reactive replacement working well with Actors is definitely needed.

i only had a little bit of rx experience but this one made me curious : why would reactive programming be a requirement for "one to one, at most once , best effort message delivery" between actors ? ( which iirc should be the only guarantee for actor to actor communication).
Rx is a very broad and generic abstraction for asynchronous communications, which brings its own share of novel issues ( at least judging by my personnal experience and the horror stories of people around me), whereas actors aim at being the most simple and straightforward way to handle concurrency and state, by acknowledging where the states should live and mutate and which shortcomings in the communication between actors have to be expected.

···

Le 24 sept. 2017 à 21:15, Marc Schlichte via swift-evolution <swift-evolution@swift.org> a écrit :

It would be great if a Swift reactive library would allow us to design ViewModels (cf MVVM) as Actors and support 2 way bindings to the UI.

Cheers
Marc

Ursprüngliche Nachricht
Von: swift-evolution@swift.org
Gesendet: 24. September 2017 4:36 vorm.
An: swift-evolution@swift.org
Antworten: mattxg@gmail.com
Betreff: Re: [swift-evolution] Standard ReactiveSteam definitions for Swift

Some thoughts as a programmer who has written an atypical reactive programming library...

You're providing protocols that strongly imply ReactiveX semantics.

Some libraries (like my own CwlSignal) look a little like ReactiveX (in that CwlSignal implements all of the ReactiveX operators) but have some quite different semantics during graph construction and during other lifecycle events. For example, CwlSignal doesn't have public Subscriber concept (responsibilities are split between the private `SignalHandler` and the `SignalSender` interface) and while the core `Signal` class is a Publisher-like concept, it is single-use which would make it a very weird implementation of this `Publisher` protocol.

These differences can make protocols for interoperability a bit of a loaded shotgun. Joining two arbitrary libraries together is likely to cause problems when the libraries have different expectations.

In some respects, it would be better to have a single, standard, concrete implementation of a class that takes an event stream input and emits an event stream. This is sometimes called a PublishSubject. A generalized PublishSubject could act as the glue between different libraries on the input and output sides. That way, the semantics of the interoperability point are fixed and each library need only ensure they support the interoperability point, rather than the semantics of every other library that could be on the other side of a protocol.

To me, I feel like this would best be implemented as part of Actor model concurrency – taking inputs and emitting outputs is fundamentally what Actors *do*.

As for naming... I would *not* recommend using `Flow` it is far too generic, has been used in very different contexts and doesn't match terminology in the field. It's fine for a library to break with common terminology for its own purposes but an interoperability interface must use the established terminology. `Publisher` and `Subscriber` are fairly clear in context but can mean very different things *outside* of reactive programming. `Observable` and `Observer` are clearer but again, the `Observer` pattern in general programming is not the same as a reactive programming `Observer` so putting it in the Swift standard library would annoy some people. On an aesthetic note, I've always found `Observer` and `Observable` difficult to read – they are similar enough that I confuse inputs and outputs when I'm tired. This is one of the reasons these terms do not appear in my library.

My personal vote is that this topic simply can't be addressed by the standard library at this point. This is something where interoperability with Swift's Actor Model should be a primary concern and until it's done, any action now is only likely to be a headache later.

Cheers,
Matt Gallagher.
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

Nothing to stop you having Observables linked to a Reactive Stream library,
the RxJava 2 library has Observables and is built on top of Reactive
Streams.

···

On Mon, 25 Sep 2017 at 5:15 am, Marc Schlichte via swift-evolution < swift-evolution@swift.org> wrote:

I hope we come up with some genuine ideas for ReactiveStreams on Swift.

For example instead of onNext()/onError() we could have a single method
which takes a Result Monad. ARC memory management might require Swift
specific solutions too.

Also on the mindset: Often I see my Android colleagues using Observables
to wait for the completion of asynchronous requests. But I think these
control flow scenarios are better handled by async/await instead.

Reactive should be used when a component (class / actor) wants to make an
unsolicited 'upcall'. As such it is firstly a modern variant of
KVO/NotificatonCenter/Delegates/target-action etc. with the additional
ability to transform / combine / schedule signals on the way from the
signal producers to the signal consumers (signal stream processing).

As KVO/Delegates probably won't work correctly for Actors (because of
execution context discrepancy), a reactive replacement working well with
Actors is definitely needed.

It would be great if a Swift reactive library would allow us to design
ViewModels (cf MVVM) as Actors and support 2 way bindings to the UI.

Cheers
Marc

  Ursprüngliche Nachricht
Von: swift-evolution@swift.org
Gesendet: 24. September 2017 4:36 vorm.
An: swift-evolution@swift.org
Antworten: mattxg@gmail.com
Betreff: Re: [swift-evolution] Standard ReactiveSteam definitions for Swift

Some thoughts as a programmer who has written an atypical reactive
programming library...

You're providing protocols that strongly imply ReactiveX semantics.

Some libraries (like my own CwlSignal) look a little like ReactiveX (in
that CwlSignal implements all of the ReactiveX operators) but have some
quite different semantics during graph construction and during other
lifecycle events. For example, CwlSignal doesn't have public Subscriber
concept (responsibilities are split between the private `SignalHandler` and
the `SignalSender` interface) and while the core `Signal` class is a
Publisher-like concept, it is single-use which would make it a very weird
implementation of this `Publisher` protocol.

These differences can make protocols for interoperability a bit of a
loaded shotgun. Joining two arbitrary libraries together is likely to cause
problems when the libraries have different expectations.

In some respects, it would be better to have a single, standard, concrete
implementation of a class that takes an event stream input and emits an
event stream. This is sometimes called a PublishSubject. A generalized
PublishSubject could act as the glue between different libraries on the
input and output sides. That way, the semantics of the interoperability
point are fixed and each library need only ensure they support the
interoperability point, rather than the semantics of every other library
that could be on the other side of a protocol.

To me, I feel like this would best be implemented as part of Actor model
concurrency – taking inputs and emitting outputs is fundamentally what
Actors *do*.

As for naming... I would *not* recommend using `Flow` it is far too
generic, has been used in very different contexts and doesn't match
terminology in the field. It's fine for a library to break with common
terminology for its own purposes but an interoperability interface must use
the established terminology. `Publisher` and `Subscriber` are fairly clear
in context but can mean very different things *outside* of reactive
programming. `Observable` and `Observer` are clearer but again, the
`Observer` pattern in general programming is not the same as a reactive
programming `Observer` so putting it in the Swift standard library would
annoy some people. On an aesthetic note, I've always found `Observer` and
`Observable` difficult to read – they are similar enough that I confuse
inputs and outputs when I'm tired. This is one of the reasons these terms
do not appear in my library.

My personal vote is that this topic simply can't be addressed by the
standard library at this point. This is something where interoperability
with Swift's Actor Model should be a primary concern and until it's done,
any action now is only likely to be a headache later.

Cheers,
Matt Gallagher.
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

--
-- Howard.

I also think that actors and signals have to be designed together:

E.g. how would you subscribe in your actor to a signal defined in another actor so that it is thread safe.

I could imagine that the signals used in actors are actors themselves ( maybe sharing the execution context of their containing actor if this is deemed to be inefficient - which should not be the case)

Cheers
Marc

···

Von: swift-evolution@swift.org

Gesendet: 26. September 2017 9:04 vorm.

An: mattxg@gmail.com; swift-evolution@swift.org

Antworten: howard.lovatt@gmail.com

Betreff: Re: [swift-evolution] Standard ReactiveSteam definitions for Swift

Comments in-line below.

On Sun, 24 Sep 2017 at 12:36 pm, Matt Gallagher via swift-evolution swift-evolution@swift.org wrote:

Some thoughts as a programmer who has written an atypical reactive programming library…

You’re providing protocols that strongly imply ReactiveX semantics.

ReactiveX can be built upon Reactive Streams, e.g. RxJava 2.0., but the idea of Reactive Streams is that the protocol is so low level you don’t interact directly with them. They seem compatible with many different styles including actors, e.g. Akka (the Akka people destined Reactive Streams I think). Reactive Streams are very actor like with one way communication links that transfer a copy of single items/errors or no items/error (pure messages).

Some libraries (like my own CwlSignal) look a little like ReactiveX (in that CwlSignal implements all of the ReactiveX operators) but have some quite different semantics during graph construction and during other lifecycle events. For example, CwlSignal doesn’t have public Subscriber concept (responsibilities are split between the private SignalHandler and the SignalSender interface) and while the core Signal class is a Publisher-like concept, it is single-use which would make it a very weird implementation of this Publisher protocol.

Nothing in the Reactive Stream specification to prevent single use Publishers, Subscribers, or Processors. The Reactive Stream specification only talks about the communication and error reporting. As long as your library has the concept of a subscription of some form you can probably write translators to the 3 protocols.

These differences can make protocols for interoperability a bit of a loaded shotgun. Joining two arbitrary libraries together is likely to cause problems when the libraries have different expectations.

Seems to work OK in the Java world, people use Akka and RxJava together.

In some respects, it would be better to have a single, standard, concrete implementation of a class that takes an event stream input and emits an event stream. This is sometimes called a PublishSubject. A generalized PublishSubject could act as the glue between different libraries on the input and output sides. That way, the semantics of the interoperability point are fixed and each library need only ensure they support the interoperability point, rather than the semantics of every other library that could be on the other side of a protocol.

This is what Reactive Streams are. They just tell you how to hook things up, how to ask for items, how to report errors, and how to finish with a connection. They do not dictate the semantics at the other end. For example your translator could throw fatal exception on an error if your library didn’t report errors or wrap the error in a Result type if it handled error in a functional way.

To me, I feel like this would best be implemented as part of Actor model concurrency – taking inputs and emitting outputs is fundamentally what Actors do.

As I have said they are very actor like and I think it was the Akka people who came up with the specification therefore I am not sure you are locking anything out. If the Swift actor model can’t interact with something as simple as Reactive Streams it will not interact with anything other than other Swift Actors, which would be very limiting. For example you would expect the Swift actors to interact with GCD, perhaps via suitable wrappers.

As for naming… I would not recommend using Flow it is far too generic, has been used in very different contexts and doesn’t match terminology in the field. It’s fine for a library to break with common terminology for its own purposes but an interoperability interface must use the established terminology. Publisher and Subscriber are fairly clear in context but can mean very different things outside of reactive programming. Observable and Observer are clearer but again, the Observer pattern in general programming is not the same as a reactive programming Observer so putting it in the Swift standard library would annoy some people. On an aesthetic note, I’ve always found Observer and Observable difficult to read – they are similar enough that I confuse inputs and outputs when I’m tired. This is one of the reasons these terms do not appear in my library.

My personal vote is that this topic simply can’t be addressed by the standard library at this point. This is something where interoperability with Swift’s Actor Model should be a primary concern and until it’s done, any action now is only likely to be a headache later.

I would prefer to move forward more quickly, I don’t think there is much risk since the specification is so low level and flexible. The whitpaper from Chris Lattner also mentions that it would be desirable for any Actor system in Swift to be compatible with Reactive Streams, so why not start now.

Cheers,

Matt Gallagher.


swift-evolution mailing list

swift-evolution@swift.org

https://lists.swift.org/mailman/listinfo/swift-evolution

– Howard.

You wouldn’t normally use Reactive Streams directly, think of them as the
Babel Fish (hitch hikers) of Streams/actors. If Swift actors talked
Reactive Stream and so did some other library, Akka, RxSwift, etc., then
the two could talk to each other. Which would be a big advantage on large
projects with multiple code bases.

···

On Mon, 25 Sep 2017 at 8:38 am, Benjamin Garrigues via swift-evolution < swift-evolution@swift.org> wrote:

> Le 24 sept. 2017 à 21:15, Marc Schlichte via swift-evolution < > swift-evolution@swift.org> a écrit :
>
> I hope we come up with some genuine ideas for ReactiveStreams on Swift.
>
> For example instead of onNext()/onError() we could have a single method
which takes a Result Monad. ARC memory management might require Swift
specific solutions too.
>
> Also on the mindset: Often I see my Android colleagues using Observables
to wait for the completion of asynchronous requests. But I think these
control flow scenarios are better handled by async/await instead.
>
> Reactive should be used when a component (class / actor) wants to make
an unsolicited 'upcall'. As such it is firstly a modern variant of
KVO/NotificatonCenter/Delegates/target-action etc. with the additional
ability to transform / combine / schedule signals on the way from the
signal producers to the signal consumers (signal stream processing).
>
> As KVO/Delegates probably won't work correctly for Actors (because of
execution context discrepancy), a reactive replacement working well with
Actors is definitely needed.

i only had a little bit of rx experience but this one made me curious :
why would reactive programming be a requirement for "one to one, at most
once , best effort message delivery" between actors ? ( which iirc should
be the only guarantee for actor to actor communication).
Rx is a very broad and generic abstraction for asynchronous
communications, which brings its own share of novel issues ( at least
judging by my personnal experience and the horror stories of people around
me), whereas actors aim at being the most simple and straightforward way to
handle concurrency and state, by acknowledging where the states should live
and mutate and which shortcomings in the communication between actors have
to be expected.

>
> It would be great if a Swift reactive library would allow us to design
ViewModels (cf MVVM) as Actors and support 2 way bindings to the UI.
>
> Cheers
> Marc
>
>
>
> Ursprüngliche Nachricht
> Von: swift-evolution@swift.org
> Gesendet: 24. September 2017 4:36 vorm.
> An: swift-evolution@swift.org
> Antworten: mattxg@gmail.com
> Betreff: Re: [swift-evolution] Standard ReactiveSteam definitions for
Swift
>
> Some thoughts as a programmer who has written an atypical reactive
programming library...
>
> You're providing protocols that strongly imply ReactiveX semantics.
>
> Some libraries (like my own CwlSignal) look a little like ReactiveX (in
that CwlSignal implements all of the ReactiveX operators) but have some
quite different semantics during graph construction and during other
lifecycle events. For example, CwlSignal doesn't have public Subscriber
concept (responsibilities are split between the private `SignalHandler` and
the `SignalSender` interface) and while the core `Signal` class is a
Publisher-like concept, it is single-use which would make it a very weird
implementation of this `Publisher` protocol.
>
> These differences can make protocols for interoperability a bit of a
loaded shotgun. Joining two arbitrary libraries together is likely to cause
problems when the libraries have different expectations.
>
> In some respects, it would be better to have a single, standard,
concrete implementation of a class that takes an event stream input and
emits an event stream. This is sometimes called a PublishSubject. A
generalized PublishSubject could act as the glue between different
libraries on the input and output sides. That way, the semantics of the
interoperability point are fixed and each library need only ensure they
support the interoperability point, rather than the semantics of every
other library that could be on the other side of a protocol.
>
> To me, I feel like this would best be implemented as part of Actor model
concurrency – taking inputs and emitting outputs is fundamentally what
Actors *do*.
>
> As for naming... I would *not* recommend using `Flow` it is far too
generic, has been used in very different contexts and doesn't match
terminology in the field. It's fine for a library to break with common
terminology for its own purposes but an interoperability interface must use
the established terminology. `Publisher` and `Subscriber` are fairly clear
in context but can mean very different things *outside* of reactive
programming. `Observable` and `Observer` are clearer but again, the
`Observer` pattern in general programming is not the same as a reactive
programming `Observer` so putting it in the Swift standard library would
annoy some people. On an aesthetic note, I've always found `Observer` and
`Observable` difficult to read – they are similar enough that I confuse
inputs and outputs when I'm tired. This is one of the reasons these terms
do not appear in my library.
>
> My personal vote is that this topic simply can't be addressed by the
standard library at this point. This is something where interoperability
with Swift's Actor Model should be a primary concern and until it's done,
any action now is only likely to be a headache later.
>
> Cheers,
> Matt Gallagher.
> _______________________________________________
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
> _______________________________________________
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

--
-- Howard.

I also think that actors and signals have to be designed together:

E.g. how would you subscribe in your actor to a signal defined in another actor so that it is thread safe.

I could imagine that the signals used in actors are actors themselves ( maybe sharing the execution context of their containing actor if this is deemed to be inefficient - which should not be the case)

How actor based signals might work can be seen in my simple actor playground: https://github.com/frameworklabs/actress

With future syntax support, this might look like:

actor class Sender {
  let signal = Signal<Int>()

  actor func start() {
    signal.emit(21)
  }
}

actor class Receiver {
  init(sender: Sender) {
    let conn1 = await sender.map { $0 * 2 }.connect(actor: self, method: Receiver.receive)
    disposeBag.add(conn1)

    // or with `actor closures`:
    let conn2 = await sender.map { $0 * 2 }.connect(actor: self) { [unowned self] value in
      print("me \(self) got \(value)“)
    }
    disposeBag.add(conn2)
  }

  actor func receive(_ value: Int) {
    print("me \(self) got \(value)“)
  }
}

···

Am 27.09.2017 um 16:37 schrieb Marc Schlichte via swift-evolution <swift-evolution@swift.org>:

Cheers
Marc
Von: swift-evolution@swift.org
Gesendet: 26. September 2017 9:04 vorm.
An: mattxg@gmail.com; swift-evolution@swift.org
Antworten: howard.lovatt@gmail.com
Betreff: Re: [swift-evolution] Standard ReactiveSteam definitions for Swift

Comments in-line below.

On Sun, 24 Sep 2017 at 12:36 pm, Matt Gallagher via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
Some thoughts as a programmer who has written an atypical reactive programming library...

You're providing protocols that strongly imply ReactiveX semantics.

ReactiveX can be built upon Reactive Streams, e.g. RxJava 2.0., but the idea of Reactive Streams is that the protocol is so low level you don’t interact directly with them. They seem compatible with many different styles including actors, e.g. Akka (the Akka people destined Reactive Streams I think). Reactive Streams are very actor like with one way communication links that transfer a copy of single items/errors or no items/error (pure messages).

Some libraries (like my own CwlSignal) look a little like ReactiveX (in that CwlSignal implements all of the ReactiveX operators) but have some quite different semantics during graph construction and during other lifecycle events. For example, CwlSignal doesn't have public Subscriber concept (responsibilities are split between the private `SignalHandler` and the `SignalSender` interface) and while the core `Signal` class is a Publisher-like concept, it is single-use which would make it a very weird implementation of this `Publisher` protocol.

Nothing in the Reactive Stream specification to prevent single use Publishers, Subscribers, or Processors. The Reactive Stream specification only talks about the communication and error reporting. As long as your library has the concept of a subscription of some form you can probably write translators to the 3 protocols.

These differences can make protocols for interoperability a bit of a loaded shotgun. Joining two arbitrary libraries together is likely to cause problems when the libraries have different expectations.

Seems to work OK in the Java world, people use Akka and RxJava together.

In some respects, it would be better to have a single, standard, concrete implementation of a class that takes an event stream input and emits an event stream. This is sometimes called a PublishSubject. A generalized PublishSubject could act as the glue between different libraries on the input and output sides. That way, the semantics of the interoperability point are fixed and each library need only ensure they support the interoperability point, rather than the semantics of every other library that could be on the other side of a protocol.

This is what Reactive Streams are. They just tell you how to hook things up, how to ask for items, how to report errors, and how to finish with a connection. They do not dictate the semantics at the other end. For example your translator could throw fatal exception on an error if your library didn’t report errors or wrap the error in a Result type if it handled error in a functional way.

To me, I feel like this would best be implemented as part of Actor model concurrency – taking inputs and emitting outputs is fundamentally what Actors *do*.

As I have said they are very actor like and I think it was the Akka people who came up with the specification therefore I am not sure you are locking anything out. If the Swift actor model can’t interact with something as simple as Reactive Streams it will not interact with anything other than other Swift Actors, which would be very limiting. For example you would expect the Swift actors to interact with GCD, perhaps via suitable wrappers.

As for naming... I would *not* recommend using `Flow` it is far too generic, has been used in very different contexts and doesn't match terminology in the field. It's fine for a library to break with common terminology for its own purposes but an interoperability interface must use the established terminology. `Publisher` and `Subscriber` are fairly clear in context but can mean very different things *outside* of reactive programming. `Observable` and `Observer` are clearer but again, the `Observer` pattern in general programming is not the same as a reactive programming `Observer` so putting it in the Swift standard library would annoy some people. On an aesthetic note, I've always found `Observer` and `Observable` difficult to read – they are similar enough that I confuse inputs and outputs when I'm tired. This is one of the reasons these terms do not appear in my library.

My personal vote is that this topic simply can't be addressed by the standard library at this point. This is something where interoperability with Swift's Actor Model should be a primary concern and until it's done, any action now is only likely to be a headache later.

I would prefer to move forward more quickly, I don’t think there is much risk since the specification is so low level and flexible. The whitpaper from Chris Lattner also mentions that it would be desirable for any Actor system in Swift to be compatible with Reactive Streams, so why not start now.

Cheers,
Matt Gallagher.
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution
--
-- Howard.
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution