8 ms·
An introduction to reactive programming
- MCRed 12y agoNothing against react or reactive, but it's yet another reaction to going down the wrong path originally -- it seems. I really don't understand why so many people jump to event driven systems when genuinely parallel computing is so easy. Specifically Erlang/elixir make it easy. EASY I tell you! Yeah, yeah, Erlang has a weird syntax. Ok, so lose two weeks learning it. But you don't even need to do that-- just learn Elixir which is pretty comprehensible right off the bat. Where's the downside? There isn't one. Yet people are going out of their way, doing all these different projects and attempts whose sole purpose is to try and fake your way around a problem that was genuinely solved 20 years ago! To be honest- and maybe I'm wrong and missing something here-- it seems like so many programmers are following what's hip and popular. V8 was a neat javascript engine, and then node cam along, so lets jump into callback hell! Why put up with that when erlang was around and well known? It's like people choose technologies based on fashion. But that seems too... pessimistic so I don't want to believe that.
- mstromb 12y agoAs someone familiar (and generally quite happy with) reactive programming, what does Erlang/Elixir do that makes it a more general, better solution? And to what types of problems, specifically? I think the reason that I picked up Rx is that it was a natural extension of LINQ, both literally and figuratively. What made Rx really click for me was thinking of it in terms of IEnumerable that explicitly acknowledged of the time domain. Since then I've come to understand some of the concepts that underlay both of them (monads, mostly), but I wouldn't have made the leap to Rx if it wasn't so easy to get there from existing knowledge. I haven't encountered anything where the next step would be "learn Erlang." You can make the argument that we should all learn about things that are unfamiliar, but there are lot of things that are unfamiliar and I haven't seen a lot of reasons why Erlang should rise to the top.
- pron 12y agoThere is a confusion of terms here. Rx is reactive programming (aka dataflow). What this article talks about -- isn't (and indeed is better served by Erlang or other similar solutions).
- TuringTest 12y agoI followed the Coursera course linked from the article and the similar "Programming Paradigms" course from Standford[1], and from what I recall, dataflow and actors where formally equivalent - i.e. you could write any one using the primitives of the other. Dataflows can be implemented through message calls to independent actors, but I also saw a stateful actor implemented as a purely functional dataflow in the shape of a sequence of its successive states. I've seen recently a lot of people from both styles saying "but that's not really what 'reactive' is" at the other, and I think it may be a misunderstanding caused by that equivalence. [1] https://www.edx.org/course/paradigms-computer-programming-louvainx-louv1-1x#.VRWGi_mWmZc https://www.edx.org/course/paradigms-computer-programming-lo...
- ihaveajob 12y agoAlan Kay argued [https://queue.acm.org/detail.cfm?id=1039523 https://queue.acm.org/detail.cfm?id=1039523] that programming is a sort of pop culture. I think this just illustrates that point.
- collyw 12y agoAs an experienced developer it is getting really grating. Why so many jobs requiring NoSQL "skills" when a relational database will solve 90% of the perceived problems. We have good mature back end frameworks. So unless you are writing a chat application, why is everyone looking to Nodejs?
- jpravetz 12y agoEasier, or at least easy, fun, less compatibility issues when you live in a pure js and json world on the front and backends, productive, good libraries, good built-in libraries, easy to deploy, productive.
- collyw 12y agoConverting to JSON is pretty easy in almost any language. And the framework I currently use is productive, has good libraries, has good built in libraries. Has a good security record and is extremely productive and stable. Deployment is one area where it doesn't shine. If that's the best reason for choosing a language I would be using PHP. And it doesn't involve JavaScript, which is in my opinion a benefit.
- jamii 12y agoI spent a total of 11 months consulting with a company that built a large (50kloc) financial system in erlang. They had terrible performance problems that were caused entirely by erlang. Imagine you have a large amount of data (order books, accounts, etc). You could put it all in on erlang process, but the gc does not cope well with large heaps (multi-second pauses). You could store the data outside the heap (eg ets) but then you pay the cost of copying on every access and have to tradeoff ease of use (more data per key) vs performance (less data per key). You could split the data up into many processes and then all your simple calculations become asynchronous protocols. Have fun debugging the math or rolling back changes on errors. I went into that contract with a fondness for erlang. Now I wouldn't touch it ever again. A naive single-threaded blocking server achieved 10x less code, 40x better throughput and 100x better latency. I used clojure, but any sane platform would have worked just as well with that design.
- Toine 12y ago50kloc is considered "large financial system" ? Just curious.
- sz4kerto 12y agoIt depends. I worked on a trading platform that >1M LOC. The overall complexity was lower than another quantitative modelling engine that only had couple of tens of thousands LOC. Complexity, work and LOC are correlated, but the correlation is not 1. In the case of the former system, 95% of the code was connectivity, GUI, persistence, etc., the actual business logic was maybe 5%. And I'm not even talking about stuff written in kdb/q, where I produced maybe 500 LOC in a month. :)
- polskibus 12y agoI'm curious whether you brought this problem up to the attention of erlang maintainers, what where their reactions and whether it will be addressed in the future. GCing large objects on the heap was (perhaps still is despite improvements) a significant problem also on .NET platform. Not sure whether this is the case, but have you considered patching the GC yourself or perhaps moving the problem to BIFs and managing that memory manually (without copying to ETS) ?
- mamcx 12y agoOk, I know a bit about Erlang and think elixir is cool. And for do a professional work, go for it is the right thing. But here the problem of "just do erlang, is better" and where the JS folks are doing BETTER is that they try to show how do things, not just say this or that is better. And look: I read that post, and because I see some functional stuff (map, filters, blah) I get the impression that was a good explain! I know... a lot of JS code around is a terrible hack, and kinda cool/sad/funny how in JS are re-inventing (and a lot of times, poorly) what is better in X.... but as marketing, they are winning. So: Where is something like this that show how build reactive properly? And I mean, build, not just use.. And hopefully in a digestible manner. I read a ton of stuff related to languages (because I wanna do one, for fun) and is like this: http://fsharpforfunandprofit.com/fppatterns/ivorytower.jpg http://fsharpforfunandprofit.com/fppatterns/ivorytower.jpg So I think some examples in how do this well and why are needed. P.D: For example, http://fsharpforfunandprofit.com/fppatterns http://fsharpforfunandprofit.com/fppatterns is probably the best advocacy that I have found about practical functional thinking. Is the reason I have trying F#!
- noelwelsh 12y agoErlang has two things that are relevant to this discussion: user level threads (aka green threads), and asynchronous message passing. User level threads reduce the memory footprint of threads, and possibly the context switch time (depending on implementation) but they are not without drawbacks. Heck, Java 1.1 had green threads but they dropped them for kernel threads in later releases (http://en.wikipedia.org/wiki/Green_threads#Green_threads_in_the_Java_virtual_machine http://en.wikipedia.org/wiki/Green_threads#Green_threads_in_...). The main issue is balancing work on multicore machines. With kernel threads the OS will automatically balance them. With green threads you are reliant on the user level scheduler to do this work. It is more difficult to get right without the level of information the OS has. If you want to give the programmer control over scheduling you need to provide some access to kernel level threads. Other issues include: not all the OS IO primitives have non-blocking equivalents you can use (typically you have to use a pool of kernel threads for these operations; the runtime may hide this.) and you still pay some context switch time with you don't actually have at all in a simple epoll / kqueue based system. I'm running out of time, so I'll just note that asynchronous message passing is hard to reason about.
- pron 12y agoCan we please stop using the term reactive programming wrong? Reactive programming[1], aka dataflow programming, is writing programs that work like a spreadsheet. Microsoft Excel is a great example of an environment for reactive programming. Functional reactive programming, or FRP, is simply reactive programing in a functional style. What we have here isn't reactive programming at all, but a few patterns (or, rather, anti-patterns) devised to avoid blocking kernel threads (only some of them are related to reactive programming). They manage to avoid blocking but at great cost. If the overhead caused by blocking bothers you, you need to understand why and realize there are far better ways of avoiding it than these anti-patterns. [1]: http://en.wikipedia.org/wiki/Reactive_programming http://en.wikipedia.org/wiki/Reactive_programming
- mstromb 12y ago> there are far better ways of avoiding it than these anti-patterns. Could you describe or at least point to some of them?
- pron 12y agoLightweight threads. They make blocking free, and allow using constructs far more suitable for imperative languages. They don't destroy your stack traces, and don't require you to re-invent exception handling and control flow. Instead of promises -- simple blocking calls (or blocking futures in some cases); instead of observables -- blocking queues (aka channels). Instead of reaching out for ways to avoid blocking, we just make blocking free.
- ninjakeyboard 12y agoReactive programming - you mean like reactive like reactive manifesto? That's not event driven. See recent published manifesto (http://www.reactivemanifesto.org/ http://www.reactivemanifesto.org/): they describe message driven paradigms, not event driven ones (now - this is a revision). But that's only a very small part of it! Recommend "Reactive Design Patterns" the free chapter from manning press: http://www.manning.com/kuhn/RDP_meap_CH01.pdf http://www.manning.com/kuhn/RDP_meap_CH01.pdf
- nemanja 12y agoThanks for the links - Reactive Design Patterns is a great read. On the bottom of the first page, they list FP, futures & promises, CSPs, observers and observables (i.e. Rx), and actors as tools of the trade. Then in the third chapter they look at each tool and evaluate it on the basis of "reactive classification" as per the manifesto (including message passing, which is one of the tenets). In my view, it is not presented as a purely reactive/not reactive dichotomy, but more of a sliding scale - a given tool may satisfy some tenets and not the rest. Actor model is arguably the most robust with respect to the proposed classification, but the authors also point out that it is not be-all and end-all and that specific problems or even portions of your system may call for different patterns.
- tbrownaw 12y agodescribe message driven paradigms, not event driven ones Messages are events. Reactive programming - you mean like reactive like reactive manifesto? That seems to be more about idealized system properties than about a style of programming. (Plus at least one bit of silliness, w.r.t. blocking / non-blocking being inherently inequal.)
- acjohnson55 12y agoNot exactly. Messages and events are dual to each other. Messages are sender centric. The sender determines the links to the receivers. The receiver listens regardless of who's sending. Events are receiver centric. The receiver explicitly chooses what senders to listen to. The sender fires off events without regard for who's listening. I'm not sure how much distinction actually matters in terms of expressive power, but it does seem to impact how the paradigms are used in practice.
- spectrum1234 12y agoI don't understand the hate for such methodologies (in the comments here) that seem to go down the wrong path. And this is coming from someone who is a strong proponent of functional programming. The problem as I see it is pure functional programmers scoff at object oriented design being so prevalent while object oriented programmers seem so biased and giddy towards OOP when they haven't even seen the light yet. How come more people don't see that both are correct? Both are the result of the market and people reacting (heh) to the market. This by definition means that both are correct but serve different purposes. What is fascinating to me is that the web has evolved enough to where user are expecting results immediately for their actions. This is an amazing time to live in. Why? Because this means the market is finally very invested in providing a fluid functional experience for the user. Since the front end is functional and the backend is OO, its very exciting times as we are the midst of real time innovation. React is just a tool to help connect these two very different pieces. Functional programmers need to get off their high horse and ask themselves why frameworks are almost entirely object oriented. Object oriented programmers need to ask themselves why they didn't think of a reactive view sooner. Both are not 100% right but functional programmers come off as d*cks when they fail to see there is no continuum of FP principles and that in the real world OOP makes sense (say to connect the pieces between say a Scala backend and React front end). You'd think they would realized this sooner though when noting, for example, that "call by name" usually is more efficient than "call by value".
- vezzy-fnord 12y agoI don't follow how "the market" validates technical paradigms as correct in any way you describe. Even assuming efficient rational actors, it has always seemed like the industry adjusts to what has low conceptual overhead and high familiarity, good advertising and at least reasonable utility. Nor do I understand how the real-time web indicates we're in an innovative age just because functional techniques are currently gaining popularity. For what it's worth, I've never been hostile to OO. I enjoy Smalltalk, I like Erlang most out of the so-called functional languages, and I've had interest in the concatenative, logic and array programming paradigms as well, where it seems most academics and HN users are ruthlessly committed to FP that they sometimes fail to recognize there's other paradigms as well.
- woah 12y agoSo many comments here critical of nonblocking code. What, exactly, is the downside? Seems to me that any downside is purely syntactical (callback hell etc. or whatever people like to say when they can't write good nonblocking code). So with nonblocking code you have the challenge of a syntax that may be difficult for some. With any variant of threading, you have the actual real programming challenge of dealing with state, locking etc. I would much rather have syntax issues than state issues. Also the only people who complain about nonblocking code are those who have been writing threads for 15 years. Why is it that something that is supposedly so bad and confusing is actually so easy for new programmers to pick up?
- acjohnson55 12y agoI find myself wondering the same thing. async-await syntaxes make asynchronous functions work pretty much the same as synchronous ones syntactically. The only drawback I can really think of is that you end up Futures going up the call stack. But this, again, seems to me to just be a detail. On the other hand, the benefits are really obvious control flow with implicit synchronization. Scala has shown that it's pretty easy to integrate asynchronous workflows with actors.