Advantage of Functional Reactive Programming over event-listeners

前端 未结 2 1983
谎友^
谎友^ 2020-12-18 00:00

I\'ve been hearing a lot about functional reactive programming, and decided to check out what the big deal is. Going through the bacon.js documentation, it seems that the ma

相关标签:
2条回答
  • 2020-12-18 00:16

    Is that it?

    No. It's about having event streams. You still will attach listener to them in the end to execute effects, but between the source and the destination you've got a very mighty abstraction.

    what's the big advantage of doing this?

    The event streams do have lots of higher-order functions to easily deal with them, and for composing them without writing out all the error-prone boilerplate code.

    As the docs put it quite nicely, bacon

    turns your event spaghetti into clean and declarative feng shui bacon, by switching from imperative to functional. It's like replacing nested for-loops with functional programming concepts like map and filter. Stop working on individual events and work with event streams instead. Combine your data with merge and combine [and wield] heavier weapons [like] flatMap and combineTemplate.

    0 讨论(0)
  • 2020-12-18 00:23

    The key point about functional reactive programming (FRP) is a syntactic property:

    The dynamical behavior of a value is specified at declaration time.

    For instance, consider a counter that can be counted up or down by pressing a button. In an imperative style, you would probably write it like this:

    counter := 0                               -- initial value
    on buttonUp   = (counter := counter + 1)   -- change it later
    on buttonDown = (counter := counter - 1)
    

    First, the counter is declared with an initial value. Then, in later parts of the code, you change the value. Now, if someone asks you the question "At any given moment in time, what is the value of counter?", you have to look at all parts of the code that reference the name counter, because that's where it could be changed.

    In contrast, when using FRP style code, the question can be answered by looking at exactly one location in the code: the place where counter is declared. For instance, in Haskell, you can write the counter as

    counter :: Behavior Int
    counter = accumulate ($) 0
                (fmap (+1) buttonUp
                 `union` fmap (subtract 1) buttonDown)
    

    The right-hand side contains all the information you need to know what the value of counter is at any given moment in time. In particular, you see that it can be changes by a buttonUp and a buttonDown, and that's it. You don't have to sift through your code, looking for places where the counter might change, no, it is enough to look at its declaration and follow up from there.

    This is the reason why FRP code is less bug-prone than event-based spaghetti code.

    See also some preliminary documentation for my threepenny-gui library.

    0 讨论(0)
提交回复
热议问题