question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Would like help in documenting Future

See original GitHub issue

Background

I am reading every inch of the docs and trying to learn about Folktale as much as I can. Recently, I decide to try Future.

Do we need a Future?

Now while I understand the difference between Task and Promise and between Task and Future ( support for cancellation ) it is not clear to me the difference between Future and Promise.

Why would I ever want to use a Future instead of a Promise ? What benefits would I have? Well, you can say: “This way you actually have a monad, instead of a sorry excuse for a monad”.

And that is a fine argument on it’s own but… having in mind I always need to convert from Promise to something else ( to future ) and that the Future’s API is pretty much the same, it is not clear to me, as someone new, why I should care about Future at all.

Code sample

Lets assume I have this function, where request is a function that makes a request and returns some results.

extractRequestInfo is a function that extracts data from the response object. If something fails, I catch the error and return an object with all the data, the badId and the error.

const requestFruit = request => data =>
    request( data )
        .then( extractRequestInfo )
        .catch( error => ( { badId: prop( [ "Id" ], data ), error } ) );

Given that this is an HTTP request, I know I don’t need a Task because there is no cancellation I can do here. So my options are Promise and Future.

Questions

  1. How would I use Future in this sample?
  2. Since this is something that can fail, should I use Result as well?

Issue Analytics

  • State:closed
  • Created 5 years ago
  • Comments:5 (3 by maintainers)

github_iconTop GitHub Comments

1reaction
robotlolitacommented, Jul 11, 2018

Future solves the same problem Promise does, so there isn’t much of a conceptual difference between the two. The difference is more in how they solve the problem.

Promises can either settle successfully or fail. In any transformation you apply to a promise’s value, errors thrown synchronously will be implicitly caught and reject the promise as well. This is interesting in async/await because you can handle these errors (synchronous and asynchronous) in a similar way–you don’t need to lift every synchronous operation into a promise, because the runtime will do that for you.

The downside of this is that it’s very easy to catch errors that you didn’t intend to, and have your system run in an inconsistent state. I don’t think you can do much with static analysis here either.

Futures don’t have that problem because nothing is lifted into a future implicitly. If you want synchronous operations to use the Future pipeline for handling errors, you have to put them there explicitly. This gives you more control over error handling, and uncaught errors will still crash the process as expected (avoiding having your program run into inconsistent memory states for cases you didn’t predict), but it takes more effort to write programs this way.

Other than that, if you consider Tasks, Futures model the eventual value of a Task with a success case, a failure case, and a cancellation case. Promises only have a success case and a failure case, so cancellation is modelled as a special failure value. This changes the idioms for handling cancellations a bit. It’s possible for code using promises to handle failures without being aware of this special cancellation value, which may be a problem since this value may easily be lost during these transformations.

In codebases that mix promises and tasks, these problems are more complicated because the implicit-lifting of errors that promises do is not very compatible with the explicit-lifiting of errors that tasks/futures expect (this can lead to problems like this one: https://github.com/origamitower/folktale/issues/163). Finding these bugs becomes a lot harder than if you had only promises or only tasks/futures. Not sure what’s the best way to handle these cases yet.


Anyway, about your questions:

  1. How would I use Future in this sample?

You can’t construct a Future directly, so you’d have to do it through a Task anyway:

const requestT = task.fromPromised(request);
const requestFruit = data =>
  requestT(data).map(extractRequestInfo).orElse(error => ({ badId: prop(['Id', data), error }));

const fruit = requestT("apple").future();

So you use Task for operations you can run more than once, and future (or promises) for representing eventual values from a particular execution, on which you may want to depend on, but without causing new HTTP requests to be made in this case.

You can think of it as a form of memoisation/caching.

  1. Since this is something that can fail, should I use Result as well?

Futures, Tasks, and Promises all have their own notion of failure, so you probably want to use that unless you want to handle different kinds of failure differently.

For example, if you’re representing an HTTP request, you might want to handle the completion of the request (i.e.: you hit the server, and it returned a response), from the semantics of the response, which may indicate an error (e.g.: the server returned a 404 response). In that case you’d probably have something like Promise/Task/Future<Result<Body, ErrorResponse>, ConnectionError>

0reactions
Fl4m3Ph03n1xcommented, Jul 19, 2018

I think I got it all now! Thanks for the help!

Read more comments on GitHub >

github_iconTop Results From Across the Web

Start Documenting Your Information Now for Future Generations
Below are a few tips for documenting your everyday life and important life events to help you leave a legacy for generations to...
Read more >
The Basics of Documenting and Analyzing Your As-Is Process
Keeping records of both current and future state documents will help everyone in the organization maintain process consistency and track progress and outcomes ......
Read more >
Importance of Documentation | The Workstream - Atlassian
Documentation encourages knowledge sharing, which empowers your team to understand how processes work and what finished projects typically look like.
Read more >
Project Documentation: Benefits, How-To and Tips | Indeed.com
Preparing project documentation can help increase your project's success rate. Here are some benefits of using project documentation:.
Read more >
What is Project Documentation, and How Can It Help Your ...
Project documentation is vital to project success. But what is project documentation? How do you make it? What documentation tools can help?
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found