they're complimentary not competition
# coroutines
j
they're complimentary not competition
šŸ‘ 3
j
What can Rx solve that Coroutines cannot?
j
multi-value cold push
also that question really makes no sense
j
RxJava is an abstraction
j
cold stream are planned feature.
j
i'm aware as evidenced by my participation in that thread
j
indeed^^
j
RxJava basically contains a tiny implementation of coroutines and there's no reason that a version of RxJava couldn't be built on top of Kotlin coroutines to great benefit
j
But once kotlinx.coroutines will have cold stream. What use case would be answered by rxJava only?
j
its operator collection
ā˜ļø 2
l
Its operator collection can also be added to kotlinx.coroutines, right ?
j
kotlinx.coroutines has even, if smaller an operator collection too. And RxJava operators are anyway not usable with kotlin channels, so the rx operator collection doesn't help if you use coroutines.
j
sure. then we've just reinvented RxJava thus proving they're complimentary concepts and not competing and we can stop these silly questions from being asked over and over
j
I think it is an interesting question. And it must be answered before going for coroutines. And if the answer is "they are complimentary" this is okay, but then the question becomes: "How do they complement each other? For what task should I chose one or the other?"
j
When most people talk about coroutines or RxJava they don't actually care about the implementation of the library they care about the programming style that it affords
Thus, most people lauding RxJava don't care about the fact that they use RxJava they care about its API abstraction. They don't care about the fact that it's manually built on threads running loopers encapsulated in Schedulers and would happily switch to the exact same API built on threads and loopers encapsulated in CoroutineContexts
šŸ‘ 1
Coroutines are just callback hell if you lack the compiler magic that does the bytecode transformation just like RxJava is callback hell if you lack the higher-level API around it
Believe me, I welcome our new coroutine overloads and look forward to a cold stream abstraction so I can drop my final RxJava usage and switch to RxKotlinCoroutineHeaven instead
j
Okay. I agree with everything you said. But, to me, it means that they do compete. Otherwise, for what task would you still use Rx?
My question is genuine interest. I'd like to know if we should still use Rx for some specific task.
c
@Jonathan I've been experimenting with a library that gives the user an API similar to Rx, but with an under the hood implementation using Coroutines to enable concurrent data flows. The implementation to enable concurrent reactive programming using coroutines is an order of magnitude simpler than trying to manage that with threads https://github.com/caleb-allen/Konko-Flow
j
@Caleb Allen Yes. I'm aware that it is possible to recreate an "rx-like" library based on coroutines. There is another similar project too, if you're interested: https://github.com/pull-vert/reactivity. But why would I need such library? What use-case does it solve better than plain coroutines with kotlinx.coroutines?
j
Oh we're linking Rx coroutine libraries? https://github.com/JakeWharton/Reagent/
we have already enumerated what it solves
multi-value cold push sources
c
My use case/experiment has been using rx-like operations to wrap these operations into easy to use dispatchers that take care of concurrency for me.
ie scaling up coroutines when we know that an operation is stateless and associative, and scaling them down when we know an operation is stateful
a
Rx & coroutines operates at a different level of abstraction IMO, they provide different ways of reasoning about the code, and they just partially overlap each other. First, Iā€™d say Rx is not primarily concerned with concurrency. Hold on, of course it has built-in tools to handle concurrency and asynchronous behaviours, but thatā€™s not the main/only reason to use Rx. Rx is more about reasoning in terms of streams. Rx is more about expressing and representing the business logic of your application in terms of manipulation and combination of these streams (usecases becomes actually observable transformers). I would consider more appropriate to compare Rx to something like say FRP (Rx intentionally is NOT by construction a realisation of FRP in the sense of the Elliottā€™s FRP work) or compare it to a more traditional, imperative, state machines. Rx is more about ā€œmonadicā€ chainability, push-based patterns, etc and itā€™s highly influenced by concepts borrowed from functional programming and category theory. Then, As a matter of fact, Rx also has another degree of freedom, namely the Scheduler, an interesting abstraction on top of threads, and people can exploit this degree of freedom to achieve asynchronous behaviour. I guess (but Iā€™ve never tried myself) there is nothing that in principle prevents someone to write a Rx scheduler on top of coroutines and power the whole Rx infrastructure with coroutines. CSP/channels etc that kotlin implements on top of coroutines are not a replacements for monadic composition, they are a model to reason about concurrent behaviour (as they are actors)
j
Kotlin Sequences and coroutines channels allow to reason in term of streams. Business logic can be express as manipulation and combination of theses streams. Coroutine dispatchers allow same abstraction as Rx schedulers. I know there are differences. But, I'm not aware of a concrete use-case for which Rx would help more than sequences or coroutines. If you know one, please share it, I'm genuinely interested.
j
multi-value cold push sources. neither channels nor sequences can model this
j
Ok, so you'r answer is "as soon as kotlinx.coroutines will provide cold stream, as they are planning to, there won't be such use-case."?
j
well except for the lack of operators that will be available and need to be rewritten
we're replaying the same conversation as above
Rx's value is its API, not its implementation
šŸ’Æ 1
j
Yes but I cannot use rx operators with coroutines channels anyway. And if I miss an operator with channels it is usually very easy and straight forward to implement it myself. So bottom line, if I have kotlin coroutines, I don't need rx.
j
you seem to be conflating rx with RxJava
there is nothing library-specific about Rx's API
j
Yes, indeed I'm conflating them, sorry for that. Every time I said "rx" I meant "RxJava"
j
Then I agree with you! Once we have that, you shouldn't need to use the library unless you're interoperating with something that requires it.
a
I know my question was a bit polemic. But I had problems in porting some Rx code to coroutines, such as setting a piece of code to react to bluetooth data only when that the remote device send them.
With Rx it is trivial: just crating a flowable an sharing these data with other observables, but with coroutines, I was complicated
l
@alucard Was it Bluetooth Classic or Bluetooth Low Energy?
a
Classic Bt
i
channels?