ReactiveX / RxRust

The Reactive Extensions for the Rust Programming Language
MIT License
493 stars 34 forks source link

What would RxRust look like? #1

Open mattpodwysocki opened 10 years ago

mattpodwysocki commented 10 years ago

How could we shape an Rx like solution in the Rust Programming Language?

Would it be as simple as?

struct Observable {

}

impl Observable {
  fn subscribe<T>(&self, observer: Observer) { 
    ...
  }
}

And then how would it look like if we used it? Could we support chaining?

steveorsomethin commented 10 years ago

I've been experimenting (and failing) with this for a while now. Two things which seem necessary are unboxed closures/capture by value and maybe a pretty way of inferring complex return types like so: http://www.reddit.com/r/rust/comments/2h26cj/functions_returning_iterators/

If you want to remain rust-y then you'd want to minimize boxing, which seems possible. I don't think you can avoid the cost of boxing/virtual calls when it comes to next'ing a list of observers though. Maybe it would be cheap enough to just copy the entire chain upon subscribe()ing instead to maintain a 1:1 relationship, and only use a subscriber list in the case of publish() and similar. At least for all of the intermediate 1:1 steps I feel like you could keep it similar to the way rust iterators work, but with an unsafe pointer backwards so you can connect to the underlying resource upon subscription. The subscriber would own a copy of the observer it subscribed to, keeping everything fast and flexible with respect to allocation choices.

rrichardson commented 10 years ago

I would start with http://rxcpp.codeplex.com/ rx-observables being the origin of rxJava/Scala/etc

We are pretty much guaranteed to make it look like the c++ implementation, which isn't bad. Then clean things up a bit, borrowing traits from Scala.

Instead of implementing the fold/reduce functions as done in c++. I would implement and depend upon Transducers ala: https://github.com/knutwalker/transducers-scala

Hopefully I'll be getting some free time this weekend. I'm going to start with the Transducers lib.

dodecaphonic commented 9 years ago

Well, now we've got unboxed closures.

rrichardson commented 9 years ago

Here is my proposal:

https://github.com/12sidedtech/reactive-rs/blob/assoc/src/reactive.rs

An echo server built using reactive components:

https://github.com/12sidedtech/reactive-rs/blob/assoc/test/test.rs

Here are most of the impls :

https://github.com/12sidedtech/reactive-rs/blob/assoc/src/processorimpl.rs

This is in a branch because I just converted everything over to Associated types. The last major thing I have left to do is implement the builder API that gives it more of a feal like IteratorExt in the standard lib. e.g. IterPublisher(myiter).map(...).reduce(...).send()

Let me know what you think :)

rrichardson commented 9 years ago

I simplified the design a bit over that found at reactivestreams.org, largely because the references/ownership thing is quite a bit harder to get right in Rust :)

Speaking of, one thing we'll need to build are adaptors for reference vs copy vs move. So far, in practice, I haven't needed it. I should also point out that I am building this as the basis for a Complex Event Processing engine in Rust.

mattpodwysocki commented 9 years ago

@rrichardson this looks great. Could we start something here for an Rx implementation? We know ownership is hard to get right, especially with our RxC++ implementation as well.

mattpodwysocki commented 9 years ago

@rrichardson would you be willing to make the initial commit? Then we could add on operators, etc. I think though getting schedulers right might be interesting as well.

rrichardson commented 9 years ago

I really don't care where it lives. I need it to exist and be actively maintained. :) I disagree a little bit with a couple of the design choices made in RxC++, but we can cross that bridge when we get there.

rrichardson commented 9 years ago

I'll put in a PR tonight, which will basically be a direct copy of what I've made, minus the cassandra adaptor, cause that dependency doesn't belong in here.

Question: Should we leave the Mio dependency? Afaik it is the only epoll/kqueue/etc event driven IO engine for rust, and is largely the reason why I built reactive.

mattpodwysocki commented 9 years ago

@rrichardson let's leave that in there. I know others are still looking at different concurrency models in Rust, so let's use it as a building block

mightyiam commented 4 years ago

I've been using RxJS for a while and I just started learning Rust. If anyone is willing to sponsor RxRust, please let me know. 'Cause I'd love to work daily on open source Rust.

mightyiam commented 4 years ago

I just found https://github.com/rust-lang/futures-rs so perhaps that's the thing in Rust and there's no need for Rx?