ReactiveCocoa (RAC) is significantly inspired by .NET's Reactive Extensions (Rx), but it is not a direct port. Some concepts or interfaces presented in RAC may be initially confusing to a developer already familiar with Rx, but it's usually possible to express the same algorithms.
Some of the differences, like the naming of methods and classes, are meant to keep RAC in line with existing Cocoa conventions. Other differences are intended as improvements over Rx, or may be inspired by other functional reactive programming paradigms (like the Elm programming language).
Here, we'll attempt to document the high-level differences between RAC and Rx.
RAC does not offer protocols that correspond to the IEnumerable
and
IObservable
interfaces in .NET. Instead, the functionality is covered by three
main classes:
- RACStream is an abstract class that implements stream operations using a few basic primitives. The equivalents to generic LINQ operators can generally be found on this class.
- RACSignal
is a concrete subclass of
RACStream
that implements a push-driven stream, much likeIObservable
. Time-based operators, or methods dealing with thecompleted
anderror
events, can be found on this class or in the RACSignal+Operations category upon it. - RACSequence
is a concrete subclass of
RACStream
that implements a pull-driven stream, much likeIEnumerable
.
RAC generally uses LINQ-style naming for its stream methods. Most of the exceptions are inspired by significantly better alternatives in Haskell or Elm.
Notable differences include:
-map:
instead ofSelect
-filter:
instead ofWhere
-flatten
instead ofMerge
-flattenMap:
instead ofSelectMany
LINQ operators that go by different names in RAC (but behave more or less equivalently) will be referenced from method documentation, like so:
// Maps `block` across the values in the receiver.
//
// This corresponds to the `Select` method in Rx.
//
// Returns a new stream with the mapped values.
- (instancetype)map:(id (^)(id value))block;