5 ms·
Thinking about this from a Haskell perspective, it seems that with promises the lambda waiting for the callback is basically encapsulated into the promise: t
by batterseapower 13y ago
Thinking about this from a Haskell perspective, it seems that with promises the lambda waiting for the callback is basically encapsulated into the promise:
type Promise a = (a -> IO ()) -> IO ()
getData :: Promise String
Whereas with callbacks you pass that around explicitly:
getData :: (String -> IO ()) -> IO ()
Promises are a monad, so you get the usual monad advantages of being able to "hide the plumbing" behind the abstraction, hence no tower of explicit callbacks in your JS code.
instance Monad Promise where
return x = \k -> k x
fmap f p = \k -> p (k . f)
mx >>= fxmy = \k -> mx (\x -> fxmy x k)
- steveklabnik 13y ago> Promises are a monad, Actually, they're not. Get ready: https://github.com/promises-aplus/promises-spec/issues/94 https://github.com/promises-aplus/promises-spec/issues/94
- jdonaldson 13y agoPromise A+ is scary bad. They're trying to shoehorn all of the functionality of a monad based implementation into a single method: http://promises-aplus.github.io/promises-spec/#the__method http://promises-aplus.github.io/promises-spec/#the__method Of course, this relies on a lot of dynamic inspection and runtime checks. Of course, this means that you can't compose with A+ promise methods in a reliable way. Of course, this means that their implementation is not going to be compatible with anyone else's. Of course, this means that everyone else's version of promises is "broken". If you're interested in approaches that follow algebraic/monad patterns, check out fantasyland spec: https://github.com/fantasyland/fantasy-land https://github.com/fantasyland/fantasy-land The name of the spec is a joke, but the spec itself is not. It's referencing a very real sentiment: That developers that want to use formal composition techniques in their js are living in a "fantasy land".
- jerf 13y agoThinking about this from a Haskell perspective isn't very helpful, because what you actually get is simply an "IO String", and it doesn't behave much like any Node option. If you want concurrency, you use forkIO, or one of the many things built on top of it (async, concurrent pipes, whatever), and if you don't, you don't. Regardless, the IO type is always "async" in the way that Node types define it (or, alternatively, transcends the way Node uses the term entirely); there is no distinction between an IO String that is simply 'return "a string"' and an IO String that actually hits a web server API to figure out what other web server to hit for a file which will then be fed to an API which will return a string... that's still just an "IO String". Haskell does have a thing from the promise tradition, but it's a different definition of "promise" than JS is using here, and it manifests in Control.Concurrent.MVar. (And, again, let me be clear, if that doesn't look like what the JS is doing here, correct. The wikipedia page is helpful. [1] AFAIK, JS is not wrong in its usage of the term promise, but there's a lot of other academic study behind the term and there's a lot of different variants in that history.) You don't need a promises monad, IO already does it, combined with the scheduler. [1]: http://en.wikipedia.org/wiki/Futures_and_promises http://en.wikipedia.org/wiki/Futures_and_promises