There's this thing called Reactive Extensions also called ReactiveX. http://reactivex.io/intro.html
The introduction has this part where it states:
"It is sometimes called “functional reactive programming” but this is a misnomer. ReactiveX may be functional, and it may be reactive, but “functional reactive programming” is a different animal. One main point of difference is that functional reactive programming operates on values that change continuously over time, while ReactiveX operates on discrete values that are emitted over time. (See Conal Elliott’s work for more-precise information on functional reactive programming.)"
Now if I want to understand/write about Reactive Extensions?
Does this mean FRP <: Reactive Extensions
So Reactive extensions should also cover FRP.
Or these two [FRP and ReactiveX] or [Continuous Time and Discrete Time] are two different concepts, should not be treated the same?
"Functional Reactive Programming" was a term coined (or made popular) by Conal Elliott. He has a precise definition for it (see also What is (functional) reactive programming?). As noted in the help document you referenced, ReactiveX doesn't meet that definition.
Given all of that, there is some overlap between the two.
In ReactiveX, time (other than serialized events, i.e., causality) is not relevant, with the specific notion of time dependent on the scheduler. The values are discrete and push-based.
FRP has, by definition, the notion of time.
And the values are continuous functions of time.
In fact, the simplest behavior in FRP is the identity function.
time :: Behavior Time
at time = id
tl;dr: FRP is a different beast altogether.
Related
When learning Scala, one of the first things I learned was that every function returns something. There is no "void"-function/method as there is, for instance in Java. Thus many Scala-functions are true functions, in a mathematic way, and objects can remain largely stateless.
Now I learned that the actor model is a very popular model among functional languages like Scala. However, actors promote a fire-and-forget style of programming, and callers usually don't expect callees to directly reply to messages (except when using the "ask"/"?"-method). Therefore, actors need to remember some sort of state.
Am I right assuming that the actor model is more like a trade-off between scalability and maintainability (due to its statefulness), and could sometimes even be considered an anti-pattern?
Yes you're essentially right (I'm not quite sure what you have in mind when you say scalability vs maintainability).
Actors are popular in Scala because of Akka (which presumably is in turn popular because of the support it gets from Lightbend). It is, not however, the case that actors are overwhelmingly popular in general in the functional programming world (although implementations exist for all the languages I'm thinking of). Below are my vastly simplified impressions (so take them with the requisite amount of salt) of two other FP language communities, both of which use actors (far?) less frequently than Scala does.
The Haskell community tends to use either STM/channels (often in an STM context). Straight up MVars also get used surprisingly often.
The Clojure community sometimes touts its own built-in version of STM, but its flagship concurrency model is really core.async, which is at its heart again channels.
As an aside STM, channels, and actors can all be layered upon one another; its sort of weird to compare them as if they were mutually exclusive approaches. In practice though it's rare to see them all used in tandem.
Actors do indeed involve state (and in the case of Akka skirt type safety) and as a result are very expressive and can pretty much do anything concurrency-wise. In this way they're similar to side-effectful functions, which are more expressive than pure functions. Indeed actors in a way are the pure essence of OO, with all its pros and cons.
As such there is a sizable chunk of the Scala community that would say yes, if most of the time when you face concurrency issues, you're using actors, that's probably an anti-pattern.
If you can, try to get away with just using Futures or scalaz.concurrent.Tasks. In return for less expressiveness you get more composability.
If your problem naturally lends itself to a single, global state (e.g. in the form of global invariants that you want to enforce), think about STM. In the Scala community, although an STM library exists, my impression is that STM is usually emulated by using actors.
If your concurrency problems mainly revolves around streaming multiple sources of data, think about using one of Scala's streaming libraries.
Actors are specifically a tool in the toolbox for handling and distributing state. So yes, they should have state - if they don't then you just could use Futures.
Please note however that Actors (at least Akka Actors) handle distribution (running location-transparently on multiple nodes) which neither functions of Futures are able to do. The concurrency aspects of Actors are a result of them handling the more complex case - networking. In that sense, Actors unify the remote case with the local case, by making the remote case be first-class. And as it turns out, on networks messaging is exactly what you can both count and build on if you want reliable, resilient and also fast systems.
Hope this answers the "big picture" part of your question.
So now with swift, the ReactiveCocoa people have rewritten it in version 3.0 for swift
Also, there's been another project spun up called RxSwift.
I wonder if people could add information about what the differences in design/api/philosophy of the two frameworks are (please, in the spirit of SO, stick to things which are true, rather than opinions about which is "best")
[Note for StackOverflow mods: This question DOES have definitive answers, the answer is the differences between the two frameworks. I think it is also highly on topic for SO]
To get started, my initial impression from reading their ReadMe's is:
As someone who is familiar with the "real" C# Rx from microsoft, RxSwift looks a lot more recognisable.
ReactiveCococa seems to have gone off into its own space now, introducing new abstractions such as Signals vs SignalProducers and Lifting. On the one hand this seems to clarify some situations (what's a Hot vs Cold signal) but on the other hand this seems to increase the complexity of the framework a LOT
This is a very good question. Comparing the two worlds is very hard. Rx is a port of what Reactive Extensions are in other languages like C#, Java or JS.
Reactive Cocoa was inspired by Functional Reactive Programming, but in the last months, has been also pointed as inspired by Reactive Extensions as well. The outcome is a framework that shares some things with Rx, but has names with origins in FRP.
The first thing to say is that neither RAC nor RxSwift are Functional Reactive Programming implementations, according to Conal's definition of the concept. From this point everything can be reduced to how each framework handles side effects and a few other components.
Let's talk about the community and meta-tech stuff:
RAC is a 3 years old project, born in Objective-C later ported to Swift (with bridges) for the 3.0 release, after completely dropping the ongoing work on Objective-C.
RxSwift is a few months old project and seems to have a momentum in the community right now. One thing that is important for RxSwift is that is under the ReactiveX organization and that all other implementations are working in the same way, learning how to deal with RxSwift will make working with Rx.Net, RxJava or RxJS a simple task and just a matter of language syntax. I could say that is based on the philosophy learn once, apply everywhere.
Now it's time for the tech stuff.
Producing/Observing Entities
RAC 3.0 has 2 main entities, Signal and SignalProducer, the first one publishes events regardless a subscriber is attached or not, the second one requires a start to actually having signals/events produced. This design has been created to separate the tedious concept of hot and cold observables, that has been source of confusion for a lot of developers. This is why the differences can be reduced to how they manage side effects.
In RxSwift, Signal and SignalProducer translates to Observable, it could sound confusing, but these 2 entities are actually the same thing in the Rx world. A design with Observables in RxSwift has to be created considering if they are hot or cold, it could sound as unnecessary complexity, but once you understood how they work (and again hot/cold/warm is just about the side effects while subscribing/observing) they can be tamed.
In both worlds, the concept of subscription is basically the same, there's one little difference that RAC introduced and is the interruption event when a Signal is disposed before the completion event has been sent.
To recap both have the following kind of events:
Next, to compute the new received value
Error, to compute an error and complete the stream, unsubscribing all the observers
Complete, to mark the stream as completed unsubscribing all observers
RAC in addition has interrupted that is sent when a Signal is disposed before completing either correctly or with an error.
Manually Writing
In RAC, Signal/SignalProducer are read-only entities, they can't be managed from outside, same thing is for Observable in RxSwift. To turn a Signal/SignalProducer into a write-able entity, you have to use the pipe() function to return a manually controlled item. On the Rx space, this is a different type called Subject.
If the read/write concept sounds unfamiliar, a nice analogy with Future/Promise can be made. A Future is a read-only placeholder, like Signal/SignalProducer and Observable, on the other hand, a Promise can be fulfilled manually, like for pipe() and Subject.
Schedulers
This entity is pretty much similar in both worlds, same concepts, but RAC is serial-only, instead RxSwift features also concurrent schedulers.
Composition
Composition is the key feature of Reactive Programming. Composing streams is the essence of both frameworks, in RxSwift they are also called sequences.
All the observable entities in RxSwift are of type ObservableType, so we compose instances of Subject and Observable with the same operators, without any extra concern.
On RAC space, Signal and SignalProducer are 2 different entities and we have to lift on SignalProducer to be able to compose what is produced with instances of Signal. The two entities have their own operators, so when you need to mix things, you have to make sure a certain operator is available, on the other side you forget about the hot/cold observables.
About this part, Colin Eberhardt summed it nicely:
Looking at the current API the signal operations are mainly focussed on the ‘next’ event, allowing you to transform values, skip, delay, combine and observe on different threads. Whereas the signal producer API is mostly concerned with the signal lifecycle events (completed, error), with operations including then, flatMap, takeUntil and catch.
Extra
RAC has also the concept of Action and Property, the former is a type to compute side effects, mainly relating to user interaction, the latter is interesting when observing a value to perform a task when the value has changed. In RxSwift the Action translates again into an Observable, this is nicely shown in RxCocoa, an integration of Rx primitives for both iOS and Mac. The RAC's Property can be translated into Variable (or BehaviourSubject) in RxSwift.
It's important to understand that Property/Variable is the way we have to bridge the imperative world to the declarative nature of Reactive Programming, so sometimes is a fundamental component when dealing with third party libraries or core functionalities of the iOS/Mac space.
Conclusion
RAC and RxSwift are 2 complete different beasts, the former has a long history in the Cocoa space and a lot of contributors, the latter is fairly young, but relies on concepts that have been proven to be effective in other languages like Java, JS or .NET. The decision on which is better is on preference. RAC states that the separation of hot/cold observable was necessary and that is the core feature of the framework, RxSwift says that the unification of them is better than the separation, again it's just about how side effects are managed/performed.
RAC 3.0 seems to have introduced some unexpected complexity on top of the major goal of separating hot/cold observables, like the concept of interruption, splitting operators between 2 entities and introducing some imperative behaviour like start to begin producing signals. For some people these things can be a nice thing to have or even a killer feature, for some others they can be just unnecessary or even dangerous. Another thing to remember is that RAC is trying to keep up with Cocoa conventions as much as possible, so if you are an experienced Cocoa Dev, you should feel more comfortable to work with it rather than RxSwift.
RxSwift on the other hand lives with all the downsides like hot/cold observables, but also the good things, of Reactive Extensions. Moving from RxJS, RxJava or Rx.Net to RxSwift is a simple thing, all the concepts are the same, so this makes finding material pretty interesting, maybe the same problem you are facing now, has been solved by someone in RxJava and the solution can be reapplied taking in consideration the platform.
Which one has to be picked is definitely a matter of preference, from an objective perspective is impossible to tell which one is better. The only way is to fire Xcode and try both of them and pick the one that feels more comfortable to work with. They are 2 implementations of similar concepts, trying to achieve the same goal: simplifying software development.
When I have used Pub/Sub pattern frameworks like MVVMLight before, I have seen that the subscriber's calls are handled synchronously. From a scalability point of view, does a reactive framework like Rx help scalability where the pub and sub are completely decoupled and scalable? Which pattern helps scalability?
I don't know the specifics of MVVMLight, but in general the Pub/Sub is a pattern, where:
Publishers and subscribers don't know about each other. They only know about a broker, where they publish/consume messages.
As a result, the publication and consumption of messages is done asynchronously and is completely decoupled. This means that the publication/consumption side can be scaled independently and in case of failures of one part, the other part is able to keep working.
Now, reactive programming is a pattern used to model changes and their propagation across multiple actors. As such, it's not so much concerned with implementation details, but more focused on providing an abstract, declarative interface, which makes it easier to work with streams of events and perform processing on top of them. Straight from ReactiveX's documentation:
ReactiveX is not biased toward some particular source of concurrency or asynchronicity. Observables can be implemented using thread-pools, event loops, non-blocking I/O, actors (such as from Akka), or whatever implementation suits your needs, your style, or your expertise. Client code treats all of its interactions with Observables as asynchronous, whether your underlying implementation is blocking or non-blocking and however you choose to implement it.
So, the decoupling/scalability will be mainly dependent on the implementation used underneath; the main benefit of the framework is mainly the abstract, declarative interface provided.
Regarding the observer pattern (which is mentioned in the question's title): it's a rather low-level primitive that can be used to achieve the same goal, but can probably lead to a much more complex codebase. For more details on the pitfalls of observer pattern when compared with more abstract reactive frameworks, you can read the following paper:
Deprecating the Observer pattern with Scala.React
The reactive programming paradigm is often presented in object-oriented languages as an extension of the Observer design pattern. You can also compare the main reactive streams pattern with the familiar Iterator design pattern, as there is a duality to the Iterable-Iterator pair in all of these libraries. One major difference is that, while an Iterator is pull-based, reactive streams are push-based.
Using an iterator is an imperative programming pattern, even though the method of accessing values is solely the responsibility of the Iterable. Indeed, it is up to the developer to choose when to access the next() item in the sequence. In reactive streams, the equivalent of the above pair is Publisher-Subscriber. But it is the Publisher that notifies the Subscriber of newly available values as they come, and this push aspect is the key to being reactive. Also, operations applied to pushed values are expressed declaratively rather than imperatively: The programmer expresses the logic of the computation rather than describing its exact control flow.
Source: https://projectreactor.io/docs/core/release/reference/#intro-reactive
For example, when analyzing live stockmarket data I expose a method to my clients
def onTrade(trade: Trade) {
}
The clients may choose to do anything from counting the number of trades, calculating averages, storing high lows, price comparisons and so on. The method I expose returns nothing and the clients often use vars and mutable structures for their computation. For example when calculating the total trades they may do something like
var numTrades = 0
def onTrade(trade: Trade) {
numTrades += 1
}
A single onTrade call may have to do six or seven different things. Is there any way to reconcile this type of flexibility with a functional paradigm? In other words a return type, vals and nonmutable data structures
You might want to look into Functional Reactive Programming. Using FRP, you would express your trades as a stream of events, and manipulate this stream as a whole, rather than focusing on a single trade at a time.
You would then use various combinators to construct new streams, for example one that would return the number of trades or highest price seen so far.
The link above contains links to several Haskell implementations, but there are probably several Scala FRP implementations available as well.
One possibility is using monads to encapsulate state within a purely functional program. You might check out the Scalaz library.
Also, according to reports, the Scala team is developing a compiler plug-in for an effect system. Then you might consider providing an interface like this to your clients,
def callbackOnTrade[A, B](f: (A, Trade) => B)
The clients define their input and output types A and B, and define a pure function f that processes the trade. All "state" gets encapsulated in A and B and threaded through f.
Callbacks may not be the best approach, but there are certainly functional designs that can solve such a problem. You might want to consider FRP or a state-monad solution as already suggested, actors are another possibility, as is some form of dataflow concurrency, and you can also take advantage of the copy method that's automatically generated for case classes.
A different approach is to use STM (software transactional memory) and stick with the imperative paradigm whilst still retaining some safety.
The best approach depends on exactly how you're persisting the data and what you're actually doing in these state changes. As always, let a profiler be your guide if performance is critical.
This question relates to project design. The project takes an electrical system and defines it function programatically. Now that I'm knee-deep in defining the system, I'm incorporating a significant amount of interaction which causes the system to configure itself appropriately. Example: the system opens and closes electrical contactors when certain events occur. Because this system is on an airplane, it relies on air/ground logic and thus incorporates two different behaviors depending on where it is.
I give all of this explanation to demonstrate the level of complexity that this application contains. As I have continued in my design, I have employed the use of if/else constructs as a means of extrapolating the proper configurations in this electrical system. However, the deeper I get into the coding, the more if/else constructs are required. I feel that I have reached a point where I am inefficiently programing this system.
For those who tackled projects like this before, I ask: Am I treading a well-known path (when it comes to defining EVERY possible scenario that could occur) and I should continue to persevere... or can I employ some other strategies to accomplish the task of defining a real-world system's behavior.
At this point, I have little to no experience using delegates, but I wonder if I could utilize some observers or other "cocoa-ey" goodness for checking scenarios in lieu of endless if/else blocks.
Since you are trying to model a real world system, I would suggest creating a concrete object oriented design that well defines the is-a and a has-a relationships and apply good old fashioned object oriented design and apply it into breaking the real world system into a functional decomposition.
I would suggest you look into defining protocols that handle the generic case, and using them on specific cases.
For example, you can have many types of events adhering to an ElectricalEvent protocol and depending on the type you can better decide how an ElectricalContactor discriminates on a GeneralElectricEvent versus a SpecializedElectricEvent using the isKindOfClass selector.
If you can define all the states in advance, you're best of implementing this as a finite state machine. This allows you to define the state-dependent logic clearly in one central place.
There are some implementations that you could look into:
SCM allows you to generate state machine code for Objective-C
OFC implements them as DFSM
Of course you can also roll your own customized implementation if that suits you better.