Skip to content

Comparison of Future Implementations

Aldwin Vlasblom edited this page Apr 8, 2016 · 38 revisions

Overview

Feature Fluture data.task Ramda Fantasy LazyEither
Resource disposal ❌ beta βœ… ❌ ❌
Cancellation ❌ beta ❌ upcoming ❌ ❌
Nice errors βœ… ❌ ❌ ❌
Async utilities βœ… βœ… ❌ ❌
Throw safety ❌ ❌ βœ… ❌
Elegant Pipelines βœ… ❌ ❌ βœ…
High performance βœ… βœ… ❌ ❌

Features

Resource disposal

Data.task can be constructed with an extra parameter, which expects a function. The function is passed down the chain and exposed as cleanup on the Task instances.

Fluture has automatic resource disposal in beta.

Cancellation

Fluture is expirimenting with allowing its resource disposal feature to be used for manual cancellation.

Nice errors

Neither data.task nor Ramda Fantasy perform any kind of type-checking on arguments passed. This often leads to very difficult to understand error messages. Fluture was created to lift that pain:

> Task.of('world').chain(thing => `Hello ${thing}!`).fork(console.error, console.log)
TypeError: f(...).fork is not a function
    at data.task/lib/task.js:117:19
    at data.task/lib/task.js:58:12
    at Task.fork (data.task/lib/task.js:114:12)

> RamdaFuture.of('world').chain(thing => `Hello ${thing}!`).fork(console.error, console.log)
[TypeError: f(...).fork is not a function]

> Fluture.of('world').chain(thing => `Hello ${thing}!`).fork(console.error, console.log)
TypeError: Future#chain expects the function its given to return a Future
  Actual: "Hello world!"
  From calling: thing => `Hello ${thing}!`
  With: "world"
    at check$chain$f (fluture/fluture.js:103:29)
    at Future$chain$res (fluture/fluture.js:229:9)
    at Object.Future$of$fork [as _f] (fluture/fluture.js:214:7)
    at Object.Future$chain$fork [as _f] (fluture/fluture.js:227:13)
    at Object.Future$fork [as fork] (fluture/fluture.js:220:10)

Async utilities

Ramda Fantasy only has Future.cache(). Data.task can be installed with control.async to gain async control utilities. Fluture comes bundled with async control utilities.

Throw safety

Ramda Fantasy prevents thrown errors from ever breaking out. When an error is thrown within one of the functions called by Ramda Fantasy, it ends up in the rejection branch of the Future.

Elegant pipelines

LazyEither is a Future with a single branch (no rejection branch) which must contain an Either. This allows it's fork method (called value) to only be passed a single continuation for more elegant pipelines.

The same effect can be achieved in Fluture by forking the Future by means of .fold(Left, Right).value(continuation).

Performance

The results from this benchmark show a significant difference between the performance of Fluture and data.task against Ramda Fantasy and LazyEither:

Fluture x 1,503,508 ops/sec Β±1.18% (91 runs sampled)
data.task x 1,397,057 ops/sec Β±0.80% (91 runs sampled)
Ramda Fantasy x 354,438 ops/sec Β±0.67% (87 runs sampled)
LazyEither x 258,136 ops/sec Β±0.70% (93 runs sampled)
Clone this wiki locally