/reactive-polyglot

FRP libraries / langs compared

Primary LanguageJavaScript

Reactive polyglot

R. (Ramda) stands for standard functional toolkit.

Operators

Current ordering is subjective: from most common operators to less common.
Operator counterparts are not expected to be fully equivalent.
"Kinda the same" is the current definition.

Presence of operator is not "good" as well as abscence is not "bad".
Every decision has it's own benefits and drawbacks. Remember, that we're trying to make analogies over systems which were be designed with different goals / philosophies in mind.

Create

Create stream from non-stream values.

KefirJS MostJS RxJS XStream
constant of / just just of
– (sequentially) – (from) of of
– (sequentially) from from ?
fromEvents fromEvent fromEvent fromEvent
fromPromise fromPromise fromPromise fromPromise
interval periodic interval + map periodic
repeat of + R.range repeat of + R.range
? iterate generate ?
? generate generate ?

Mapper

Modify events one to one.

KefirJS MostJS RxJS XStream
map map map map
– (map) constant mapTo mapTo
delay delay delay combine(delay(500))
– (map) timestamp timestamp – (map)

Transforms

Modify events * to *.

MostJS RxJS XStream
scan scan fold
chain / flatMap flatMap map + flattenConcurrently
map + switch switchMap / flatMapLatest map + flatten
concatMap concatMap map + flattenSequentially
join mergeAll flatten
loop scan + map fold + map
– (custom) bufferWithCount ?

Filters

Skip events by predicate or signal.

MostJS RxJS XStream
filter filter filter
skipRepeats distinctUntilChanged dropRepeats
skipRepeatsWith – (scan) dropRepeats
skip skip drop
take take take
slice skip + take drop + take
skipWhile skipWhile fold + filter + map
takeWhile takeWhile filter + endWhen
since / skipUntil skipUntil fold + filter + map
until / takeUntil takeUntil filter + endWhen
during window + take(1) ?

Combinators

Combine multiple streams into single.

MostJS RxJS XStream
merge merge merge
combine combineLatest combine
sample withLatestFrom sampleCombine
sampleWith sample ?
zip zip ?
concat concat concat
ap combineLatest ?

Side effects

Produce side effect for every event.

MostJS RxJS XStream
tap do / tap debug

Ending

Operators which target end event somehow.

MostJS RxJS XStream
empty empty empty
never never never
continueWith ? concat

Concurrency

MostJS RxJS
– (custom) amb / race

History

MostJS RxJS
– (custom)

Design diffs

RxJS

  1. Three primitives: Observer, Observable, Subject.
  2. Observables end on error.
  3. Provides API to handle errors.
  4. Does not provide API to handle ending.

KefirJS

  1. Two primitives: Stream and Property. Properties have "current value" notion.
  2. Observables does not end on error (by default).
  3. Provides API to handle errors.
  4. Provides API to handle ending.

MostJS

  1. One primitive: Stream.
  2. Separate packages for subject-like and property-like primitives.
  3. Provides API to handle errors.
  4. Provides API to handle ending.

XStream

  1. One primitive: Stream.
  2. Always multicast. A Stream is like an RxJS Subject.
  3. Streams end on error.

Common

RxJS does not emit initial scan value as event (use startWith for that).

Rx.Observable.interval(100).map(x => 1)
  .scan(add, 0);
  .subscribe(console.log); // 1--2--3--...

Most.periodic(100, 1)
  .scan(add, 0);
  .observe(console.log); // 0--1--2--3--...

Found docs / API quirks

MostJS

startWith vs sampleWith vs continueWith + recoverWith vs skipRepeatsWith
(val vs none vs func vs stream)

tap is listed in "Transform" section.

RxJS

startWith is listed in "Combine" section.

mergeAll is listed in "Combine" section.

distinct is not listed in "Filtering" section.

takeUntil is not listed in "Filtering" section.

just / return should be deprecated in favor of of.

fromArray should be deprecated in favor of from.

Links

bacon-vs-kefir – BaconJS vs KefirJS API comparison

dataflows – web arch. dataflow comparison

stream-conversions – tool for cross-library stream conversions

Additional Read

cujojs/most#171

https://twitter.com/rpominov/status/689566111734599683

tc39/proposal-observable#66