6 ms·
I personally don't like the reactive model especially with RxJava. You quickly end up in Observable hell.
by vips7L 6y ago
I personally don't like the reactive model especially with RxJava. You quickly end up in Observable hell.
- jswny 6y agoI agree. Having used reactive Java and the Elixir/OTP model of message passing, I can safely say that I'd never go back to reactive Java unless I was forced to. It feels like you are fighting the language the whole time.
- vips7L 6y agoHopefully Loom will be our savior.
- lliamander 6y agoI haven't used reactive Java, but I have used the async/await model of JS as well Erlang/OTP, and I definitely prefer message passing. The mental model is so much easier to reason about.
- zmmmmm 6y agoIt's a shame because it seems to me like RxJava is eclipsing what was previously a pretty fertile ecosystem of Actor based approaches, but RxJava itself is not very nice to use compared to those which are much more natural.
- apta 6y agoLoom should solve all that.
- unscaled 6y agoI think Loom is thrown around too haphazardly here. Loom will present an ergonomic alternative for concurrency that is strictly superior to futures, but it will not replace or significantly simplify RxJava[1]. Project Loom is also orthogonal to actors - it really doesn't dictate any specific concurrency model, it just provides fiber support in the JVM. We will definitely see actor libraries once project loom is released, but these are already available now, and they are not widely used. The only thing Loom can help them with (I hope) is better performance, but I don't think that's the reason the actor model lost ground in the Java world. [1] Project Loom can be the basis for some minor simplifications, as JetBrains did in kotlinx.coroutines.flow.
- mping 6y agoI have never used Rx libraries. What are the cases where you have low friction coroutines such as loom (no "coloured" functions afaik) where you want to use RxJava? Handling backpressure? Modelling complex flows? Honest question
- apta 6y agohttps://wiki.openjdk.java.net/display/loom/Main https://wiki.openjdk.java.net/display/loom/Main
- MrBuddyCasino 6y agoIt is terrible, and has hidden gotchas. Use it only if you really really have to, then check if you can't do it in Kotlin instead with native async/await syntax, and only if the answer to those questions is "no", continue to shoot yourself in the foot.
- The_rationalist 6y agoThe reactive model is not here because people like it but because it enable to do optimizations that are normally mostly impossible to do. The real breakthrough is to use reactive programming + Rsocket which allow true asynchronous real time applications. And rejoice yourself, Kotlin Flow/coroutines has a clean API that feels synchronous and that still manage to be reactive streams compliant! It's mostly perfect and project loom will be the ice on the cake! Others platforms (non JVM) really have a lot to learn in this regard
- diroussel 6y agoHave you got any links, or can you explain the optimisations that are possible in RxJava? I've done some vert.x and creating new Futures all the time is a bit cumbersome, but I understand it. With RxJava it's another layer on top, and you are even more removed. The whole non-blocking experience in java feels like there is a lot of plumbing. I know it's fast for IO reasons, but it really feels like the JVM/CPU has to jump through a lot of glue code to make it work.
- The_rationalist 6y agocan you explain the optimisations that are possible in RxJava? Here's the fundamental problem that reactive programming solve: Here's a kotlin function from https://kotlinlang.org/docs/reference/coroutines/flow.html#suspending-functions https://kotlinlang.org/docs/reference/coroutines/flow.html#s... suspend fun foo(): List<Int> { delay(1000) // pretend we are doing something asynchronous here return listOf(1, 2, 3) } This function is not reactive but it is at least async. suspend ~= async keyword in js or C# As you can see its return type is not colored: List<Int> In inferior languages you would have a Promise<List<Int>> and need to check yourself for its resolution before accessing the value. (Promise == CompletableFuture) But this is not what matters here This example function is will be executed asynchronously, it will do processing on a list then return the list. It means that it will need to wait for all elements of the list to have been processed each before being able to use the result. The big idea is that with reactive streams we can process list elements asynchronously, individually https://kotlinlang.org/docs/reference/coroutines/flow.html#flows https://kotlinlang.org/docs/reference/coroutines/flow.html#f... fun foo(): Flow<Int> = flow { // flow builder for (i in 1..3) { delay(100) // pretend we are doing something useful here emit(i) // emit next value } } A flow is just an asynchronous list, an array of CompletableFutures if you want. Each time you emit() a value from the flow, the processed element will be received at call site, on demand Beyond this base idea, reactive programming add on to of it many useful concepts like: Cancellation primitive, automatic multithreaded dispatching, lazy or eager evaluation, many things and the ability to choose a specific scheduler (a blocking io friendly one for example) Reactive streams are fantastic ideas but API wise even with reactor it needed a lot of boilerplate and had incidental complexity. Kotlin flow bring the best of both world and is to me the state of the art asynchronous programming model, transcendanting goroutines.
- _bxg1 6y agoI've used a reactive model on the front-end for several years now (MobX at one job and then RxJS at another) and haven't encountered anything I would call "Observable Hell". I will admit that cascading side-effects can be hard to debug, but they're also a code smell. The whole point of the reactive pattern, IMO, is allowing you to have as few open-ended side-effects as possible. i.e., reactions that change state (instead of re-computing a pure function) should be scrutinized heavily and kept to a minimum. If they're kept to a minimum, then in my experience they remain manageable and fairly easy to reason about.
- thecupisblue 6y agoOh, you didn't do it in java. The mere boilerplate and heaviness of the language makes it Observable hell. Well, it got improved with lambdas the last time I used it, but it's still a clusterfuck of Observables, Singles, wrappers and knee-deep stacktraces. JS allows you a lot more flexibility as a language and it is a far better experience using RxJs.
- leonidasv 6y agoMicronaut supports Kotlin coroutines since 1.3. You're mostly stuck to Rx outside Kotlin, tho.
- zmmmmm 6y agoIt's wrong to focus on the reactive part - it's a feature that it is fully supported, but Micronaut is a generic framework that has both synchronous and async support. It's real secret sauce is the ability to make API building extremely concise, well type checked and performant (for JVM based apps - 10-100ms scale startup times etc.). For example, this is a Hello World API in Groovy (this is almost literally the entire Application): @Controller('/hello') class HelloController { String index() { 'Hello World' } }
- Nursie 6y agoWhile that is concise, the sparkjava version (without boilerplate): get("/", (req, res) -> "hello world") Is just as clear to me. Not saying micronaut doesn't have things to offer, but simplicity of setting up an http endpoint isn't unique.
- zmmmmm 6y agoSure - I was mostly just responding to the commenter implying that Micronaut leads you to "observable hell". The point is, if you apply it in standard synchronous mode it's just like any other framework these days.
- bcrosby95 6y agoAs someone that uses Java in my dayjob, I wish annotations were never invented. Debugging problems with them is hell. Why can't we just use method calls?
- pjmlp 6y agoBecause method calls don't compose as compiler plugins or runtime reflection. They were also not invented by Java, other languages like Dylan, Python and .NET actually go them first. Actually they are like a poor man's Lisp macros kind of.
- deleted 6y ago[deleted]
- mister_hn 6y agoBut I also hate to see my colleagues spawn threads and polling the whole time waiting for something happening, all without timeout