Skip to content

Comparison of Future Implementations

Aldwin Vlasblom edited this page May 15, 2017 · 38 revisions

Overview

Feature Fluture data.task Ramda Fantasy Fun-Task
Resource disposal βœ… βœ… ❌ ❌
Cancellation βœ… βœ… ❌ βœ…
Nice errors βœ… ❌ ❌ ❌
Async utilities βœ… βœ… ❌ βœ…
Exception catching ❌ ❌ βœ… βœ…
High performance βœ… βœ… ❌ ❌
Continuation guarding βœ… ❌ ❌ βœ…
Stack safety βœ… ❌ ❌ ❌

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 hook(acquire, cleanup, consume) for managing resources.

Cancellation

Allows for cancellation of running computations.

Nice errors

Most libraries don't perform any kind of type-checking on arguments passed. This often leads to very difficult to understand error messages. Fluture is the exception:

FunTask.of('world').chain(thing => `Hello ${thing}!`).run({success: console.log, failure: console.error})
TypeError: spawned.run is not a function
    at fun-task/lib/index.js:702:33
    at success (fun-task/lib/index.js:682:32)
    at Of._run (fun-task/lib/index.js:376:7)

> DataTask.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)

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.

Exception catching

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. This is arguably not a good thing, as documented by this section on error handling. FunTask can catch thrown errors for you, and separates them to a third branch.

Performance

Fluture and Data.Task have significantly better performance than other similar libraries.

Continuation Guarding

Fluture and Fun-Task ensure that a continuation can only be called once. Calling reject or resolve after the first call has no effect.

Stack safety

Fluture ensures that any transformations, including recursive chain, have a constant stack usage. This means that one can map, ap, chain, etc. as much as they'd like over the same structure without causing the fork or cancel functions to blow the stack.

Clone this wiki locally