10 ms·
JavaScript Promises Discussion: Make Them Monadic? (2013)
- adreamingsoul 9y agoWhat about it?
- turbohz 9y agoThis is an old discussion (which I had followed for years). The proposal, afaik, was never accepted into Ecmascript. So we ended up with half baked Promises. In a particular nodejs project I worked on, I overrode the native Promise implementation with the one provided by Pacta, but was not ideal (promises returned by other modules where native, ...) Not doing nodejs work anymore, but I'm still rather disappointed about how Ecmascript promises were ultimately delivered.
- Lazare 9y agoYeah. Native promises are usable, and they're okay... ...but with only a few small changes they could have been much better, and it's frustrating to see proposal to make them better back when that was an option denied out of hand with such arrogance and (to my mind) lack of understanding of what was even being discussed. The linked thread of comments has not aged well over the years. (And it's doubly frustrating now that the (excellent!) async/await syntax has now been built on top of it. What a wasted opportunity.)
- rockymadden 9y agoFor those looking for monadic Promises, I’d suggest taking a look at Fluture (https://github.com/fluture-js/Fluture https://github.com/fluture-js/Fluture). It’s a wonderful library and with do-notation, ability to work with callbacks, nodebacks, and Promises, I haven’t looked back. It also has adheres to Fantasy Land, Static Land, and has defintions for santuary-def.
- dahart 9y ago> It also has adheres to Fantasy Land, Static Land, and has defintions for santuary-def. I think I understood a couple words in that sentence, like "it" and "has". :P Looking up fantasy-land, I found https://github.com/fantasyland/fantasy-land https://github.com/fantasyland/fantasy-land. I would like to better understand these monads everyone is talking about. But, just to be super honest -- and possibly completely wrong -- the terminology is really off-putting. At a glance it just feels super complex, academic and completely divorced from practical coding. I get vibes of enterprise java class hierarchies looking at this stuff. I hope I'm wrong, and I really am interested to learn more about it, but I can see from the OP's linked thread that I'm not alone feeling this way. It's not at all clear why I should be thinking about my JavaScript algebraically at all times, or what the practical advantages are. After decades of coding, I'm just getting more alergic to complexity, and this feels like complexity. What are some good online resources that might help me change my mind and see the light?
- gcommer 9y agoThis is one of the better javascript FP books that ramps into fairly advanced concepts: https://mostly-adequate.gitbooks.io/mostly-adequate-guide/ https://mostly-adequate.gitbooks.io/mostly-adequate-guide/ A simpler, gentler introduction is available from https://www.manning.com/books/functional-programming-in-javascript https://www.manning.com/books/functional-programming-in-java... > At a glance it just feels super complex, academic Agreed, because unfortunately, it is. (I might substitute "complex" with "hard" -- the ideas are actually very simple; understanding the big picture of how they fit together is hard) > It's not at all clear why I should be thinking about my JavaScript algebraically at all times, or what the practical advantages are. The main goal is to be able to write more and more code as pure functions -- this is hopefully an accepted best practice: functions with minimal inputs and no tangle of global state/context are far easier to reason about, test, and with proper data design, reuse. But you quickly run into an issue: how can I write pure, stateless functions when dealing with inherently stateful surroundings (IO, DOM, database, etc.). That's what all this category theory jargon is about.
- heycato 9y agohttp://www.tomharding.me/ http://www.tomharding.me/ <-- excellent
- Shoothe 9y agoAsync/await is the do-notation for Promises and generators can be re-purposed as do-notation for any other monad, see e.g. https://curiosity-driven.org/monads-in-javascript#do https://curiosity-driven.org/monads-in-javascript#do
- maximexx 9y ago> JavaScript Promises Discussion: Make Them Monadic? No, just totally ditch them! I can't help to hate Promises. Sometimes I have to work on a code base that is completely baked with them, it's just a nightmare. With the stupid async await implementation things haven't got any better.. Now they expect me to write async calls in a try-catch block!?! With JS I prefer to use simple callbacks until they come up with a proper async await without try-catch and Promises bullshit. Callback hell happens not because of the callback principle itself. It exists because it's too easy to keep nesting functions. Most devs simply don't know how, or are too lazy, to apply good patterns for using callbacks.
- tomc1985 9y agoThis. Every time I try and get up to speed on those things it's like, "wtf? this is actually better?"
- jey 9y ago> Now they expect me to write async calls in a try-catch block!?! What do you mean? In my experience, the use of async/await leads to much cleaner code for I/O driven tasks like querying APIs and databases. Yes, I do have a try/catch at the top of the callstack to catch and log unexpected errors.
- vorpalhex 9y agoasync/await worries me, not for abstract language reasons but because it hides complexity in a way not friendly for junior engineers. I imagine a lot of code that should be thought out and made parallel being forced into a synchronous flow. Note that promises aren't a ton better in this regard, and come with a ton of confusion themselves. In short, async is hard.
- jey 9y agoPromise.all() does a pretty good job of parallelizing tasks while maintaining readability.
- orf 9y ago
- moomin 9y agoSuch a dumb discussion. One guy saying “Here’s a proven design”, someone else calling it “Typed Language Fantasyland”.
- baristaGeek 9y agoIt's not a dumb discussion at all. Callback hells and managing threads synchronously/asynchronously as desired are a big deal.
- nawgszy 9y agoI am surprised to see so much venom against Promises expressed here. I am young, but I began coding (as a profession) just when Angular 1 was popular and I remember callback hell was a real thing. A few years later, I use Promises a lot, and they work really well. The way errors bubble is logical and easily controlled, it's almost impossible to throw an unhandled promise exception, doing 'parallel' tasks is easy with ```Promise.all([])```, and there's pretty limited complexity with the way a Promise always returns a Promise. I find the simplest way to use them is to define a class that has a few data properties you'd like to track. class Handler { constructor() { // shared variables can be set / reset here this.defineInitialState(); } executeAction() { return ( this.promiseFn() .then(() => this.anotherPromise()) .then((passedArgument) => this.promiseExpectingArgument()) .then( // success case () => this.successHandler(), (err) => this.errorHandler() ) ); } } It's modular and you know what to expect (it's always a promise!). Sure, it's imperfect, but I think its weakly opinionated simplicity is a good tradeoff. After all, it makes no distinction of whether any of the functions in that chain were synchronous or not, and that's a nice thing to know. It also makes testing with dummy sync functions in place of actually asynchronous ones a 0-effort integration. I don't know about this async / await keyword stuff, and if you have to wrap it in a try/catch block, that's unfortunate but also seems like it's not the end of the world. After all, isn't the Go language constantly requiring you to say "if err != nil <your code>"? Explicit error handling isn't even a bad thing. Anyways, this is just my opinion, it's fair to have your own, and maybe other languages handle asynchronicity more gracefully, but from what I've seen this is a clean way to wrap async OR sync code in a context that makes it always behave predictably and readably.
- djtriptych 9y agoAgreed, it was a HUGE improvement over callback soup. The only cleaner methods I’m familiar with are CSP (as implemented in clojure and go, and to some extent in JavaScript with libraries like RX and Bacon). Basically you’re treating steams of events as first-class values. That’s a rather functional/mathy way to treat concurrency/parallelism but I’ve found it illuminating.
- Lazare 9y ago
- yuchi 9y agoSeeing Jeremy resurfacing old threads brings me memories. Anyway this was a nice thread to follow while it happened.
- MBCook 9y ago(2013)
- dang 9y agoThanks, added.
- mikewhy 9y agoI'm confused, and am not very knowledgeable about FP (though I am very interested in it). Can anyone explain how the 3 bullet points in the issue aren't already in Promises? > Promise.of(a) will turn anything into promise. This just looks like `Promise.resolve(a)` > Promise#then(f) should take one function, not two. That's applicable, but you could try limiting yourself to only using one argument. > Promise#onRejected(f): move onRejected to prototype instead of second arg. `Promise#catch(f)`?
- tel 9y agoThe issue with `of` is that it special cases when `a` is already a Promise. Promises try hard to not be nested (a promise of a promise) but that nesting is critical for algebraic properties. The then issue is multifarious. On one side, splitting the two uses makes the algebraic justification for then more clear, but it's not a big deal. The real issue is that `then(f)` does different things when `f` returns a Promise. This breaks in the same way that `of` did—you need to be able to discuss nested promises.
- BigJono 9y agoThat just raises more questions. Can anyone here give a concrete example of a real world problem that is more cleanly solved with these changes to the Promise spec? There's a lot of talk about FP and type theory here, and none about actual work. To me, all this stuff is still in the "cool to play around with at home" category. But until it affects day to day dev work, there's a whole set of people that aren't going to give the slightest fuck.
- pka 9y ago> But until it affects day to day dev work, there's a whole set of people that aren't going to give the slightest fuck. That's a seriously toxic attitude to have. People are using monads and other FP concepts daily to simplify "day to day dev work" (here's an example [0].) The fact that it's more or less mainstream to write off a concept because it sounds "academic" is worryingly anti-intellectual in a profession that is allegedly based in analytical thinking. > Can anyone here give a concrete example of a real world problem that is more cleanly solved with these changes to the Promise spec? There are some in the linked github thread (which had to be reposted repeatedly until people actually stopped and read them, btw.) It's about being able to write DRY code that abstracts over not only promises, but anything else that forms a monad, like arrays, optional values, and so on. [0] https://github.com/facebook/Haxl https://github.com/facebook/Haxl
- vinylkey 9y agoFun fact: the JS library Fantasy Land [1] got its name from that discussion [2]. [1] https://github.com/fantasyland/fantasy-land https://github.com/fantasyland/fantasy-land [2] https://github.com/promises-aplus/promises-spec/issues/94#issuecomment-16176966 https://github.com/promises-aplus/promises-spec/issues/94#is...
- rexpop 9y agoI am so happy to know this lineage, thank you!
- shados 9y agoIve been following Fantasy Land since times immemorial, but I never knew thats where the name came from (even though I followed the legendary discussions around the spec back in the days). Only today when I reread it did I notice the fantasy land call, and told myself "Omg...THAT is where it came from!"
- rmrfrmrf 9y agoAnother fun fact: the guy who mocked devs asking for monadic Promises later "championed" and subsequently withdrew the TC39 proposal for Promise cancelation, presumably after realizing that it's impossible to shoehorn into the current spec cleanly.
- shados 9y agoHaving followed the promise cancellation proposal pretty closely, especially when it came to a close, it sounded more like he got sick of the pushback (specifically mentioning push back internally at Google) if my memory serves. I won't pretend to speak for him, but I don't recall him withdrawing the proposal because he didn't think his solution was correct. He just didn't want to deal with the detractors anymore. Of course, it was a solution to a problem he created, so... (to be fair, the JavaScript world was very different then than it is now, in the same way ES6 classes would probably work very differently if they were designed today)
- marknadal 9y agoI was never on the promise bandwagon because they never did anything useful other than create hype with developers around using a more functional approach - which is good, but promises themselves add no benefit. For instance, people previously would do: ``` start(x => doA(y => doB(z => doC(end)))) ``` When they could have just used named functions, with promises or not, it is just that promises was hype that taught them good programming skills: ``` doA = x => doB(x) doB = y => doC(y) doC = z => end start(doA); ``` As with promises: ``` start.then(x => x) .then(y => y) .then(z => z) .then(end) ``` The only real value of a promise now is being able to use `await`, which is the real first-class language magic. However, the future isn't even with promises, so there is no need to change or modify them. The future is chain reaction programming, also goes by the name of observables/FRP/stack-based-cocatenative-programming/railway-programming. Programming Chain Reactions is great, because they can also downconvert easily to `await`, so you get the best goodies of all the world. We've implemented observable/FRP/chain-reaction programming as the default API in https://github.com/amark/gun https://github.com/amark/gun , it is really quite pleasant language abstraction. However, FRP/etc. hasn't quite hit "mainstream" hype yet, so developers do not know what they are missing out on. Once you try it and it "clicks", you realize the future is truly bright. :)
- marcosdumay 9y agoWebAssembly can't come fast enough. Really: > @pufuwozu can you show with a concrete example why you can't write the example code you posted with promises? Why couldn't him just give a concrete example of what he was claiming that was impossible?
- odammit 9y agoI feel like I’m being promised a burrito.
- tyingq 9y agoI wonder why we have to resort to terms like monadic, immutable, orthagonal, etc, in our field so often. I feel weird and elitist using these terms when more common ones suffice and are understood by my customers.
- dionian 9y agowhats a better term here?
- tyingq 9y agoContextual functions maybe? For orthagonal, it's often used to mean "unrelated". Immutable could be "fixed", "constant" or any number of other more pedestrian terms.
- kccqzy 9y agoYou're just inventing your own terms no one else uses. There's a page called "Monad (functional programming)" on Wikipedia https://en.wikipedia.org/wiki/Monad_(functional_programming) https://en.wikipedia.org/wiki/Monad_(functional_programming) suggesting that the term "moand" or "moandic" is widely used and understood. There's no page called "contextual function." There's a page called "Orthogonality (programming)" on Wikipedia https://en.wikipedia.org/wiki/Orthogonality_(programming) https://en.wikipedia.org/wiki/Orthogonality_(programming) also suggesting that the term "orthogonal" is widely used and understood. The page for "Unrelated" is about a movie. There's a page called "Immutable Object" on Wikipedia https://en.wikipedia.org/wiki/Immutable_object https://en.wikipedia.org/wiki/Immutable_object suggesting that the term "immutable" is widely used and understood. "Fixed" and "constant" have distinctly different meanings from "immutable."
- tyingq 9y agoI do respect your viewpoint. But immutable and orthagonal are just weird jargon to my project managers, product managers, analysts, customers, etc. For me, it's somewhat equivalent to odd terminology that probably irritates you from the business like "synergy" or "paradigm", or "incentivise" From the tech side, we parody those terms. Rest assured, business folks parody us for our monads, immutables, etc. It makes us seem like we're trying to feel self important. Wikipedia isn't really convincing to me. There's no page for contextual functions because it's not really new, exciting, unique, or notable. I feel the same if you call that "monads". I can implement them in decades old programming languages. Same for immutable. Existed long before anyone called it that. We used it without having to have some catchy moniker that nobody understood outside the family. Basically, I want to stop alienating project managers, product managers, and customers with weird jargon.
- redleggedfrog 9y agoUm, the problem here is Javascript. Don't use a cesspool of a language and you don't have such banal conversations.
- deleted 9y ago[deleted]
- pier25 9y agoHonestly, I think Promises with async/await and try/catch are good enough for a lot of use cases. Certainly lightyears ahead of callback hell. IMO the next big thing will be Observables.