4 ms·
The rx fallacy is to make you believe that programming at the most general abstract level is the best. It’s just wrong. An array is not a stream, an observable
by bsaul 9y ago
The rx fallacy is to make you believe that programming at the most general abstract level is the best. It’s just wrong. An array is not a stream, an observable that can fire at any time isn’t the same as a predefined list of things.
Whenever you abstract a data structure, you loose some meaning, some peculiarities that helps you understand what you’re doing.
Rx should be used by framework or low level libraries developers, to factor code. But it should be almost invisible to the api user.
- coldtea 9y ago>The rx fallacy is to make you believe that programming at the most general abstract level is the best. It’s just wrong. Citation needed. >Whenever you abstract a data structure, you loose some meaning, some peculiarities that helps you understand what you’re doing. That's obviously not true. The whole idea is to abstract over peculiarities that are not needed (implementation details for example). So, you "loose some meaning, some peculiarities that helps you understand what you’re doing" only some times (when you abstract badly) and not "whenever you abstract a data structure". >Rx should be used by framework or low level libraries developers, to factor code. But it should be almost invisible to the api user. That makes even less sense - having abstraction as the hidden lower level. The whole point of abstraction is giving a higher level interface.
- bsaul 9y agoAbstraction is, by definition, reducing different things to a shared subset of their attributes. Eg : the concept of "Human" is an abstraction over all the different attributes of all the individuals, to reduce them to the ones they all share. If i say i met a "human being", you can't tell if it's a "he" or a "she", if he has dark of blond hair, etc. What you can tell, is that it has a heart and a brain, stand on at most two legs, and has at most two arms. That could be all you need to deduce a few things, but by saying so, i kept some details hidden from you. Now, if we get back to rx, its whole purpose is to work with the concept of "streams of events". Noting that many data structure and patterns (such as iterators over arrays, or event source observation) can be thought a specific kind of even streams. This lets you define stream-combination operations, that work on all those structure. Which may, sometimes, be convenient. The problem is when people start telling you that the generic tools around Rx Stream (producer, consumer, publish subject, etc) are the best tools to model the behavior of all your application, because "everything is in fact one big giant stream of events". And then you end up with code monstruosities, because you realize that it's more complicated than that. Maintaining a UI state and mutating it becomes a nightmare, you start wrapping every native structures (such as arrays) into Observers just to perform the equivalent of a join, etc. Either the stdlib and frameworks are "reactive", and then using rx pattern would be invisible, or you're going to have a horrible code. In some way, it's exactly like generics, or base superclass : you define them in the stdlib, for example to share code between Sets and Arrays, but what the end user is manipulating 99% of the time isn't "Iterable". It's Arrays and Sets.
- CuriousSkeptic 9y agoThe problem is that Rx isn’t about “streams of events”. The main interface, IObservable, is entirely about _subscribing_ to “streams of events”. It’s the awful brittleness of handling those subscriptions that makes it so hard to program with. Compare that to something like signals in Elm (originally, it has changed now) while it makes some things Rx allow you to do impossible reports from users are that once it type checks “it just works”
- breatheoften 9y agoAn interesting podcast on the topic where the creator of elm discusses the creation (and removal) of signals in elm. https://overcast.fm/+HSqxOglhQ/17:21 https://overcast.fm/+HSqxOglhQ/17:21
- flor1s 9y agoSignals have been part of FRP since the first papers about it were published twenty years ago (about FRAN)
- sunir 9y agoYou don’t need citations in a comment thread discussion, the same way I don’t ask my friends over beers for citations when they imply the Maple Leafs is a hockey team. We all know that is false.
- coldtea 9y agoI'm all for not giving citations if it's: (a) something well established that one can look up, (b) not a matter of hard science (I could care less for "soft science" citations, most are BS ideology du jour + whatever pays for grants), (c) the other side gives actual arguments (in which case I can evaluate them) (d) the other side puts the issue as a personal preference (e) if it depends on perspective / worldview / morals For other cases, if one insists something is objectively better/worse, they can be useful.
- sunir 9y agoYou can provide citations but you should not demand citations in a salon atmosphere.
- proc0 9y agoProgramming is arguably the process of abstracting data (and functions which are also data). Abstraction does hide information, but it does so to expose the essentials. Good abstraction should lead to DRY code. Streams are a form of abstraction that allow for __pure__ functional "event" patterns. OOP world like JS events and event handlers, allow mutations and have no problem sending messages with objects to process. The problem with this from a pure functional paradigm is that it isn't very composable. Two functions called one after another may not always compute the same thing if they each respond to random events whenever. The solution is to create a "stream" abstraction, and to have specific data types handling different types of streams. By thinking of events as streams, you now have a "neutral" signal that you tap into, and you just wait until you have a message. Without explaining and going into details, this allows for composable, pure function 'events'. To summarize, streams are taking mutable event patterns into the world of pure (immutable) functional "event" patterns. And this is good if you already are convinced mutations are bad (different topic).
- bsaul 9y agoPure functional only takes you so far. If you’re using transient servers to process http queries that has no local state, then the frp abstractions are probably a good fit. When you’re dealing with an app or a single page web app, you’re spending the whole user session mutating one big state (represented on the UI). Every events are going to apply some diff over that big state, and so what you have in practice is a stream of effects.
- proc0 9y agoFRP is purely functional. Side effects can be managed with pure functions using Monads, and Streams are also Monads because of the interface they implement.