4 ms·
I'm well aware of promises, thank you. I'm also well aware that there's very little difference in reality between a promise-based style of coding and a callback
by sreque 9y ago
I'm well aware of promises, thank you. I'm also well aware that there's very little difference in reality between a promise-based style of coding and a callback one. You still lose stack continuity, it's still much harder to chain operations that hop stacks, it's still a nightmare to debug compared to stack-based programming, etc.
If you've ever actually implemented a promise it's even easier to see how little promises actually get you. Given a callback-based API, it's absolutely trivial to wrap it in a Promise-based API. Fundamentally this is because promises give you very little in the end on top of callbacks beyond some syntactic sugar.
- ralusek 9y agoFirst of all, I have absolutely implemented promises from scratch, and it IS trivial. However, "callback hell" is a reference to writing code with deeply nested callbacks, particularly with manual error handling at each level, both of which promises completely negate. If you want to change the topic from "callback hell" to debugging across stacks, then we can do that. There was some work with "domains," since moved to AsyncListener/Continuation Local Storage to keep context across stack calls, but I don't disagree that improvements in this department are the place that NodeJS paradigm would currently benefit from most.
- sreque 9y agoIt's still "callback hell" because you're still fundamentally writing code where you invoke an API and pass in a callback to handle the results. The fact that the callback you pass in happens to be a promise that allows you to stage other callbacks and/or promises doesn't really change things enough for the label "callback hell" to be inaccurate in my opinion. A different programming paradigm, for instance, would be the use of delimited continuations such that the API you invoke suspends the current call stack, executes the I/O operation, then resume the call stack with the result of the I/O operation. Very few languages support that. One reason is that natively supported continuations in the programming language has far reaching consequences in terms of performance. I'm not an expert on golang, but I believe this is essentially how goroutines are implemented: https://groups.google.com/forum/#!msg/golang-nuts/t3g8NbITYEI/RqJbKWeDCAAJ https://groups.google.com/forum/#!msg/golang-nuts/t3g8NbITYE... Also keep in mind that I'm not 100% against callback-based programming. I have, for instance, implemented a non-blocking client for a custom TCP-based protocol using Netty. The client performed better than a blocking version that it was meant to replace. I played around with using Promises in conjunction with the library but ended up preferring callbacks to Promises for a number of reasons, some of which are specific to the JVM.
- Johnny_Brahms 9y ago> A different programming paradigm, for instance, would be the use of delimited continuations such that the API you invoke suspends the current call stack, executes the I/O operation, then resume the call stack with the result of the I/O operation. guile has recently gotten guile-fibers which works like this. It is really an amazing way to do concurrency.
- dleslie 9y agoCallback hell may as well be synonymous with stack incoherence. The hell arises from not knowing from whence you came.
- ehsanu1 9y agoHow about that await though.
- mahyarm 9y agoHow do you get stack continuity in anything that is multithreaded unless the debugger adds special support for it?
- sreque 9y agoBy programming using synchronous blocking code within a single thread, of course.
- vilmosi 9y ago>>> I'm also well aware that there's very little difference in reality between a promise-based style of coding and a callback one. Then you're not using promises as they are intended to be used.