Rxdart: Should we call this RxDart or something else?

Created on 16 May 2017  路  14Comments  路  Source: ReactiveX/rxdart

Overall, we want to make it easy for peeps coming from other languages to dive right into Dart, with all of the Rx power they're used to in other languages. We want to fit into the Dart ecosystem, and so we've based RxDart's Observable on Dart's Stream class. However, it's important to fundamentally understand Streams before diving into Observables, and there are some fundamental differences between Streams in Dart and Observables from the ReactiveX Contract. When those differences arise, we've decided the best thing to do is favor fitting into the Dart ecosystem over following the ReactiveX spec.

Despite the differences between Dart Streams and Rx Observables, they're conceptually very similar, and we hoped calling it RxDart would make it easy for folks to get going quickly.

What we've seen, however, is a decent amount of confusion, and so we wanted to open a ticket and leave it open for a bit:

Should this library actually be a ReactiveX / RxDart library, or should we rename it to reinforce the fact that we are extending Stream, and that Streams are the most important thing to learn and understand? Has the name been helpful or confusing to you? Thanks for your feedback!

Most helpful comment

thank you for including me in this conversation!

Ok, I'll be the bad guy here 馃槂

As evident in this thread https://github.com/ReactiveX/rxdart/issues/88. In the beginning, I got confused just like @adaojunior. I would get examples in RxJS/RxSwift and try to do the same thing with RxDart but it would work differently.

At the end of the day I think that RxDart should be as close to canonical implementations of Rx (like RxJS, RxJava, etc.) as possible disregarding or bending where needed the dart stuff.

My perspective is that, even though it is important to grow dart community and have support of native Stream and other features, it is more important to adhere to standards of the larger body of cross-language polyglot community of Rx. The benefits it will give outweigh disadvantages.

People coming to dart who know rx from other languages can be productive from day one. which in turn would make their adoption of dart faster, safer, and easier. It removes barriers and obstacles of adoption which will help bring more people to dart. Like any tool and product dart needs to make it as easy as possible for new people to get onboard. If there's a steep learning curve and confusion than that process will slow.
It's a funnel and we could optimize one of the steps of that funnel here. When you make a new hammer you don't want to have new users to read a long manual on how to use it before they can start. It's a hammer, it should work like any other hammer, even though this time it is made of shiny durastil 馃槃

Another thing is that ideas from rxjs, rxjava, rxswift, etc. could be easily transferred and applied to rxdart and vice versa if it adhere's to standards meaning there is a facilitated knowledge exchange which reinforces all of the communities and parties involved.

Please keep in mind though that my position is coming from a background of a developer who is a polyglot and is switching languages often to achieve goals on various projects. I value consistency and common architecture, design patterns, and approaches across the languages and platforms.

All 14 comments

Would love to hear from @alexvbush, @lestathc and @adaojunior if y'all have time!

When I first tried to use this library I got confused because I was trying to compare other implementations with this one, when I had a problem, I googled and usually I would get an answer with an example on JS/Java but it would be different on rxdart.
Overall, I believe extending Stream is more important to me than being 100% compatible with Rx.

I also think the long-term success depends on being close to Dart, while being close to Rx is mostly for a lower entry hurdle.

Perhaps there could be some helper classes that one doesn't need to use, but can use to get more Rx-like experience.
I don't know if such an approach could work well though - just a thought.

thank you for including me in this conversation!

Ok, I'll be the bad guy here 馃槂

As evident in this thread https://github.com/ReactiveX/rxdart/issues/88. In the beginning, I got confused just like @adaojunior. I would get examples in RxJS/RxSwift and try to do the same thing with RxDart but it would work differently.

At the end of the day I think that RxDart should be as close to canonical implementations of Rx (like RxJS, RxJava, etc.) as possible disregarding or bending where needed the dart stuff.

My perspective is that, even though it is important to grow dart community and have support of native Stream and other features, it is more important to adhere to standards of the larger body of cross-language polyglot community of Rx. The benefits it will give outweigh disadvantages.

People coming to dart who know rx from other languages can be productive from day one. which in turn would make their adoption of dart faster, safer, and easier. It removes barriers and obstacles of adoption which will help bring more people to dart. Like any tool and product dart needs to make it as easy as possible for new people to get onboard. If there's a steep learning curve and confusion than that process will slow.
It's a funnel and we could optimize one of the steps of that funnel here. When you make a new hammer you don't want to have new users to read a long manual on how to use it before they can start. It's a hammer, it should work like any other hammer, even though this time it is made of shiny durastil 馃槃

Another thing is that ideas from rxjs, rxjava, rxswift, etc. could be easily transferred and applied to rxdart and vice versa if it adhere's to standards meaning there is a facilitated knowledge exchange which reinforces all of the communities and parties involved.

Please keep in mind though that my position is coming from a background of a developer who is a polyglot and is switching languages often to achieve goals on various projects. I value consistency and common architecture, design patterns, and approaches across the languages and platforms.

I agree that there are notable advantages being familiar to Rx users,
but it also could alienate developers who like Dart streams and might not want to use this package if it doesn't feel like Dart.

@zoechi I'd say that this is fine. They are not, in my opinion, the target audience of this library. Dart people who want to use streams will use streams.

I fully understand your concers, the thing is, Dart Streams are so tightly integrated into everything, that in my opinion there is no choice but to follow suit.

Take dart:html, want to listen for a change event? Use element.onChange which presents a Stream.

Angular, need to expose an Output for your component? Provide a Stream.

And that's just one problem, on a Dart stream, you can do distinct. But this will only compare the current event to the last event, so coming from rx, this is DistinctUntilChanged.

The list goes on unfortunately.

The Dart authors obviously looked at rx, but ended up doing something else, ending up kind of halfway.

Sidenote: when I proposed rxdart to the rx initiative, the first question was: does it play nice with AngularDart? It does, but with a price to pay...

Thanks for the comments! I actually agree with you overall, @alexvbush. Rx should be Rx. Due to the implementation of the Stream class, there are numerous differences that are starting to add up, making it confusing. We literally cannot comply with the Observable contract in some areas.

That said, I agree with some other other folks here that I'd like to create a library that works very fluently within the Dart ecosystem. Therefore, I think it might be a decent idea to rename this repo. That should hopefully slightly cut the mental ties with Rx that seem to be confusing, give us the leeway to consider different naming (I think one could argue BehaviorSubject is a very odd name), and continue use the ReactiveX operators and class system as inspiration for features so that we essentially have feature parity.

Whatcha think?

@mattpodwysocki Could you please give your input on this? It feels like we have consensus from the authors that we'd prefer to rename this repo and remove it from the ReactiveX github org.

Some clarification:

The Dart authors obviously looked at rx, but ended up doing something else, ending up kind of halfway.

I'm not sure when the first Rx version the Dart authors could have seen came out. RxJava saw it's first commit in late 2014 and went 1.0 in 2015. The Stream api went to bleeding edge in Dart in 2013. By the time developers started expecting to see distinctUntilChanged it would have been breaking to rename Stream.distinct.

There is a lot to be said of the fact that Rx implementations are much better known that Stream in Dart - and there is a lot of value in an implementation that can be picked up without learning anything new coming from such a popular library. I think in the end, though, it's going to be hard to develop for long in Dart without learning something new and using Stream.

There are a few high level approaches, and each has drawbacks, I think the first 2 are what are being discussed here.

  • Extend Stream with new methods inspired by Rx. Drawbacks:

    • Stream has different semantics and some existing methods that make it impossible to be 1:1 and the differences, when they pop up, can be a hurdle for devs coming from an Rx background

    • Some noise in translating from a Stream coming from somewhere else (dart:html) into an Observable that can be used in the way devs expect

  • Avoid Stream entirely and implement Observable independently with matching semantics to other languages. Drawbacks:

    • Impossible to interop well with any existing Dart code. Once you have to translate from Stream to Observable you're back to breaking the semantics devs expect. So only code that is 100% Observable already will feel right, and that excludes anything from the sdk, or AngularDart, or package:async, or...

  • Implement some of the most useful bits using the StreamTransformer interface. Drawbacks:

    • More noise at usage sites clicks.transform(debounce(duration)) rather than clicks.debounce(duration)

    • Semantics don't match Rx 100% so need to learn Stream

I think there is room for multiple approaches in the Dart ecosystem. FWIW the last approach is the one used by package:stream_transform which is very recent.

@natebosch Thanks for the thoughtful response!

"I think in the end, though, it's going to be hard to develop for long in Dart without learning something new and using Stream."

This is an excellent summary of our feelings, and why we want the library we write to fit fluently into the Dart ecosystem as a matter of priority. However, as you said, favoring Dart has meant losing consistency / ease of adoption for our users and an inconsistent API with the major implementations out there.

We therefore believe it's the best idea at this time to rename this repo, stress the fundamentals of learning Streams first and that our library is a set of power tools built on top of it.

Sidenote:

It's interesting, RxDart actually takes both #1 and #3 approaches :)

We've got a base layer of StreamTransformers, and the Observable class is simply syntactic sugar over that layer. We even export our StreamTransformers as a separate package!

Going forward, I think we were planning to keep our stream transformers base (or perhaps contribute them to your project?), and move away from the Observable name / strict contract which causes the confusion you mention. We can then ensure the naming works idiomatically in the Dart ecosystem, without being too foreign to newcomers.

All:

I'm ok with moving it out of the group if the group feels like the Rx base is no longer a fit for Dart's needs. I still like the idea of Rx + Dart which is to say that it could be analogous to ReactiveCocoa versus RxSwift, so say ReactiveDart being the name here.

Sorry for the late.

For my experience, both DartStream and Rx defines the async event sequence using different assumptions. No reason (and not easy) to let DartStream fully accept the Rx's semantic and vise versa. They present similar concept, but the differences also make it harder to implement some operators to meet both requirements.

IMO, it is good to call this an advanced functional reactive programming extension for DartStream, no need to say it is a Dart implementation for Rx, though there are 90% of operators are same. This gives user a clear picture that I can use this lib to perform FRP, and if I was a Rx user I can easily start, but it also tell me that this is not Rx, I should take care of the differences.

Even people are not writing full FRP app, FRP operators are still very useful to make life easier, like debounce for user input box, switch for async call cancelling. So, this lib is still the great improvement for existing Stream.

Thanks

Thanks all! Really appreciate all the feedback :) I think we can call this one closed.

Actions:

  • Pick a new name! #98
  • Rename & Move the repo to a new org
  • Rename classes and Update documentation
Was this page helpful?
0 / 5 - 0 ratings

Related issues

frank06 picture frank06  路  3Comments

egorikem picture egorikem  路  8Comments

BugsBunnyBR picture BugsBunnyBR  路  7Comments

SAGARSURI picture SAGARSURI  路  4Comments

cedvdb picture cedvdb  路  4Comments