3 ms·
I've prototyped UIs with RxJS (the javascript version of reactive extensions) both by itself and with Cycle.js. I've also used reactive programming in Perl 6. T
by muraiki 11y ago
I've prototyped UIs with RxJS (the javascript version of reactive extensions) both by itself and with Cycle.js. I've also used reactive programming in Perl 6. There are a lot of things to like about reactive programming, but anymore I'm not sure if it's the right answer. Let me first preface this by saying that I'm building upon thoughts presented (by someone else) here: http://blog.paralleluniverse.co/2015/08/07/scoped-continuations/ http://blog.paralleluniverse.co/2015/08/07/scoped-continuati...
One problem with reactive programming (and also with promises), is that you are essentially using monadic composition in an imperative language. Because of the lack of special support for monads that you have in a language like Haskell, you have.to.chain.flow.control.methods. As a result of this, you lose access to the standard flow control the imperative language provides you, and you also generally end up with mangled stack traces. Now I know that rxjs5 is working on the stack trace problem through the usage of a recursive scheduler, but I'm not sure how this works on the Java side of things.
An alternative approach can be found in languages like Go and Erlang. In these languages you generally do not need to worry about exhausting a thread pool because they have made creating "threads" extremely cheap. As such, you can write normal imperative code that blocks, potentially indefinitely, and also still preserves stack traces and which uses the plain flow control structures (and error handling) of imperative programming.
Furthermore, if you couple this approach with CSP, you can leverage specialized systems that can "prove" (to a "good enough" level vs a mathematical proof level, although the latter is probably possible) that your design is correct. I'm not certain if a similar capability exists for reactive streams. See http://reaktor.com/blog/why-csp-matters-ii-how-do-i-know-sync-works/ http://reaktor.com/blog/why-csp-matters-ii-how-do-i-know-syn...
Now granted, this discussion may be overkill for a small app that needs a little bit of reactivity. The article does mention that they are using this only for networking code. I've tried to use it in a much more general way, and I'm not yet fully convinced that it's the right approach in a typical imperative/OO language. Of course, if it seems like adding green threads to the language is nontrivial, as may be the case with javascript, then perhaps rxjs is the best option after all. :)
- nickcage 11y agoI think Functional Reactive is the right way. Do you know Elm ? http://elm-lang.org http://elm-lang.org
- muraiki 11y agoI'm familiar with Elm but haven't used it. I may not have properly communicated my point: FRP + imperative can be messy, and can force you to abandon the basic building blocks of an imperative language. It seems that Elm was designed from the ground up for FRP, so I have no objection to its use there.
- WorldMaker 11y agoAs you point out, RxJS "Next" (~5) should simplify things a bunch. On the other side (promises), EcmaScript standardization is progressing towards getting async/await baked into the language. There's also a slow lag, but native promise debugging support in browser dev tools is getting better. Some of that too is making sure to switch to libraries that take advantage of native promises when available (still a lot of promise libraries in the wild that are not aware of native promises).
- _pmf_ 11y ago> One problem with reactive programming (and also with promises), is that you are essentially using monadic composition in an imperative language. Because of the lack of special support for monads that you have in a language like Haskell, you have.to.chain.flow.control.methods. As a result of this, you lose access to the standard flow control the imperative language provides you, and you also generally end up with mangled stack traces. Now I know that rxjs5 is working on the stack trace problem through the usage of a recursive scheduler, but I'm not sure how this works on the Java side of things. Your point is kind of validated by C#'s introduction of async/await at the language level. If Rx extensions for .NET would have lived up to their promise (and those are much, much more mature that the poor man's imitation that is RxJava), there would have been no need to introduce a completely unrelated mechanism for doing async work (and mandate its usage in the Universal Windows Platform).
- bsaul 11y agoI'm having trouble following this thread of conversation : isn't reactive more about restructuring your app as a composition of event streams that trigger actions and GUI state changes, rather than just simply performing async tasks ? Fwiu, It tries to have you build your app as a static tree of flows, in a descriptive manner. It's a much broader goal.
- EvanPlaice 11y agoJust wait until JS gets the :: function bind operator. This wil yield 2 significant benefits. First, Instead of the current hacky approach to implementing monads in JS, by which I mean adding operator methods to the observer 'monad' protype it'll be possible to use truly functional monads. Mixed with async functions I'd expect unnecessary blocking to become a non-issue and traditional prototype method chaining to become an anti-pattern. Second, since it isn't necessary to add the operators at runtime it'll be possible to include them as separate ES6 module imports. That means, RxJS as well as any other library that extensively uses method chaining (ex lodash, jQuery) will finally benefit from tree shaking. If this works the way I've been led to believe, minamilist libraries like jqlite will die off and Rollup.js will become the the de facto linker for building JS packages.