3

Besides lazy execution, are Tasks and Promises pretty much the same thing? When I refer to a task, I refer to a class that is in its most basic behavior like the following:

class Task {
  constructor(then) {
    this.then = then;
  }
  map(mapper) {
    return new Task((resolve, reject) => this.then(
      x => resolve(mapper(x)),
      reject
    ))
  }
  flatMap(mapper) {
    return new Task((resolve, reject) => this.then(
      x => mapper(x).then(resolve, reject),
      reject
    ))
  }
}

What type of (class?) is a task/promise? I'm learning about functional programming approaches, but I don't think I've gotten to this type yet. Is it a type of monad?

MFave
  • 1,044
  • 2
  • 8
  • 19
  • [Lazy evaluation](https://en.wikipedia.org/wiki/Lazy_evaluation) implies sharing of computations and results, which your `Task` implementation does not. To me, it looks like the [Kleisli arrow](https://en.wikipedia.org/wiki/Kleisli_category) for the `Promise` monad. (Which - yes - is a monad as well, as its `flatMap` method implies, however it's missing the `of`/`return` method) – Bergi Oct 30 '17 at 03:56
  • Just read this article which I thought was pretty informative: https://glebbahmutov.com/blog/difference-between-promise-and-task/ – Ben Oct 30 '17 at 03:56
  • My bad, I meant deferred execution with something like fork. Which is of course, not present as a method in my very basic representation of Task. – MFave Nov 01 '17 at 13:39

2 Answers2

3

Yes, the key thing is a monadic bind, or a flatMap in your case that has the signature:

Task A -> A -> Task B -> Task B

With promises - that's the then method that:

Promise A -> (A -> Promise B) -> Promise B
 this          onFulfilled        return value

In fact, both are instances of the Continuation Monad. Lots of other things (like Rx streams) are instances of the continuation monad.

Promises in JavaScript however are specced with a slightly different (and uglier, for arguably practical reasons) signature with it being possible to also return a plain value from then, and there are exception semantics involved.

There was a push for more "monadic" promises back in 2013 when they were specced, but it failed. The current promises in JavaScript aren't really "monad"s per-se.

Benjamin Gruenbaum
  • 270,886
  • 87
  • 504
  • 504
  • And I’m assuming that Task also has no internal “pending” / “fulfilled” state like promises do? – MFave Nov 01 '17 at 13:41
  • @MFave why would you assume that? If you mean task by https://github.com/kriskowal/gtor/blob/master/task.js then it has state. – Benjamin Gruenbaum Nov 01 '17 at 13:46
  • Just my naivety with respect to how these things work. It comes along with functional programming’s “stateless as much as possible” sort of approach, but I guess in this case you can’t avoid It. – MFave Nov 01 '17 at 14:04
1

A.promises are one refactoring step further than callback.just that. if you have a function

const f = x =>  x * x ;

1) Use Callback and remove return type

you can pass a callback and remove the return type. This the famous Continuation-passing style

const f1 = (x,callback)=>callback(x*x);

What if we curry the action and return it as a result ?! we could do this :

const squareCont = (x)=>callback=>callback(x*x);

if you look at this for a long time and rename callback to resolve you will see that this is actually a promise.

//i rewrited it to make it clearer
var squareCont = function(x){
   return function (resolve){return resolve (x*x);}
}

[Side Note : we could make it into a Promise if we enclose the callback into an object that exposes a then function like that :

const squarePromise = (x)=>({then:callback=>callback(x*x)});

squarePromise(2).then(r=>console.log(r))

check the fiddle here] B.Task is the Coninuation Co-Monad . Because i cannot summarize it here you can read in more detail here : Promises & Continuation Monad in JavaScript and here Async/await a.k.a Continuation Co- Monad in JavaScript

Dimitris p
  • 21
  • 6
  • This doesn't answer the OP's question. Nowhere are you even attempting to describe the difference between promises and tasks. Furthermore, a promise is not a `Cont`. It's a lot more complicated than that because the value of the promise may not be readily available. Hence, you have to maintain a list of listeners to update when the value is finally available. Finally, the comonad implementation of Lazy that you linked to doesn't follow the laws of a comonad. – Aadit M Shah Apr 04 '19 at 08:41
  • @AaditMShah who said the promise is a Cont ???? Please refer to this article in order to understand why lazy Can form a co-monad. Thanks http://davesexton.com/blog/post/monads-and-comonads-and-linq-oh-my.aspx https://bartoszmilewski.com/2017/01/02/comonads/ – Dimitris p Apr 04 '19 at 16:32
  • @AaditMShah you cannot have a list of listeners with promises there is only one resolve . The one you are talking about is the [link](https://en.wikipedia.org/wiki/Observer_pattern) observer pattern which is implemented by Observable/observer in Reactive extensions .Please Do not answer irrelevant uninformed things ,just to make an impression. – Dimitris p Apr 04 '19 at 17:27
  • @AaditMShah see the discussion on promises here [How to resolve a promise multiple times? .You can't. Promises can only be resolved once.](https://stackoverflow.com/questions/46416433/how-to-resolve-a-promise-multiple-times) Sorry to break it to you there can only be one Then for each promise .you comment :"It's a lot more complicated than that because the value of the promise may not be readily available. " the observer pattern you are referring to is actually pretty simple, if you think is complicated then you might want to read more in depth until you grasp it .Thanks – Dimitris p Apr 04 '19 at 17:29
  • You said that a promise is a `Cont`, and I quote, "if you look at this for a long time and rename __callback to resolve you will see that this is actually a promise.__" No, it's actually not a promise. Also, I know what I am talking about because I actually wrote a [standards compliant Promises/A+ implementation](https://stackoverflow.com/a/36192729/783743). Finally, you do need to maintain a list of listeners because although a promise can only be resolved once, yet multiple listeners can be waiting for the promise to be resolved. – Aadit M Shah Apr 05 '19 at 02:30
  • Sure, Lazy is a comonad. I never said that it wasn't. I said that "the comonad implementation of Lazy that you linked to doesn't follow the laws of a comonad." Look, I get that you're trying to promote your blog, which is great. However, before you do so just make sure that you're not spreading misinformation. I don't have anything against you. I'm not trying to impress anybody. I don't have any hidden agenda. I'm just saying that your answer is not on point because it doesn't address the OP's question, which asks for the difference between promises and tasks, and that it has mistakes. – Aadit M Shah Apr 05 '19 at 02:50