Open mattpodwysocki opened 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.
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.
Well, now we've got unboxed closures.
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 :)
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.
@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.
@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.
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.
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.
@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
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.
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?
How could we shape an Rx like solution in the Rust Programming Language?
Would it be as simple as?
And then how would it look like if we used it? Could we support chaining?