6 ms·
More reactive usually means less global state, which is generally for the better. It also encourages functional purity where possible. Previously (briefly) in i
by ajconway 7y ago
More reactive usually means less global state, which is generally for the better. It also encourages functional purity where possible.
Previously (briefly) in iOS/macOS there was an attempt to move to closure-based APIs, which led to unreadable tangles of function invocations with often surprising calling threads.
Before that for a long time there was a weak delegate object pattern, probably the least convenient way of interacting with things.
- pjmlp 7y agoIt also means more memory being used.
- skohan 7y agoAt least with closure based code, you can set a breakpoint and see the chain of executions which led to your critical portion. With FRP, basic flow of control is surrendered to the scheduler, and your stack trace doesn't tell you anything. The other thing I'm not a fan of with FRP is that it makes the assumption that it's somehow good to deal with everything through one big unified abstraction layer. Rather than just dealing with your concrete business logic, you also have to set-shift to think about the flow of your program in terms of abstract chains of observables. This level of abstraction makes the interfaces in your code less clear as well. For instance, with the delegate pattern, you can take a look at the protocol of the object you're consuming and get a clear idea about what the intent of that protocol is. In an FRP world, your interface point might be an Int-valued observable, which could be just about anything. To see how it's going to behave, you have to go see how that particular observable is defined in the calling context, which might end up being some chain of map-zip-filter-debounce operators which further obfuscate the intent. More abstraction rarely makes a program more readable or more performant, and FRP is all about abstraction. Also I think you're poking at a false dichotomy with reference to things like global state, and functional purity. It's very possible to write simple, imperative code which makes use of pure functional programming, and immutable state. FRP puts you in kind of a "jail" which encourages you to produce code with those properties, but it comes with a lot of unnecessary costs as well.
- ajconway 7y agoThere is no dichotomy here, it's perfectly fine to use imperative code where it fits better. I would not agree that using any particular technology makes code less clear. Also, I'm not sure how protocol interfaces, callback-based interfaces and reactive event sources differ in readability as they all basically provide a way to call your code at (without referring to documentation) random times.
- DrScientist 7y agoDoesn't an application still have a state, even if you don't store/manage it explicitly? Isn't a program more understandable if that state is sometimes made explicit rather than implicit? Also if your goal is 'functional purity' then you might want to read this article from ten years ago. https://prog21.dadgum.com/55.html https://prog21.dadgum.com/55.html
- ajconway 7y agoThe state is there, of course. The goal here is to minimize the amount of state the code has access to at any particular time. Functional purity is not the goal, it's just one way to reduce state.
- DrScientist 7y agoSo you still have state, but you can't get at it because it's been moved from the heap to the call stack? I'm not sure that makes programs: 1. Easily evolve-able. 2. Easy to understand. Well managed accessible state can be greatly simplifying. In my view the goal should be simple understandable code, not a meta-goal like removing all accessible state.
- ajconway 7y agoI don't know, actually. Should the state other that what the task (or sub-task) can observe matter for it to function? Where would be the boundary, as there are lots of things happening simultaneously in a computer, and the global state is huge.
- bradstewart 7y ago> Well managed accessible state can be greatly simplifying. Absolutely--and functional programming is one way to achieve that. From the perspective a given function, all "state" is captured in its inputs and outputs. You know exactly what existing state can be used by the function (inputs) and exactly what state can be generated by the function (outputs) simply from looking at the signature.