4 ms·
> This is wrong. Async "callbacks" in Javascript cannot have semantically meaningful return values, because a callback context cannot read the values. EVERY la
by KirinDave 8y ago
> This is wrong.
Async "callbacks" in Javascript cannot have semantically meaningful return values, because a callback context cannot read the values. EVERY lambda has a return value in Javascript, but this is more an implementation detail of dynamic typing than a statement of intent. They don't have callers that accept values of any type, so they're effectively a function of (Context -> IO ()). They're executed strictly for side effects.
If you have a meaningful return value, it's not properly called a callback. You can google about this because obviously the "spec" is "how it is used in literature and the common vernacular." As an example, the first SO hit on Google I say has top rated answer saying " An async callback function can return a value, in other words, but the code that calls the function won't pay attention to the return value." https://stackoverflow.com/questions/6847697/how-to-return-value-from-an-asynchronous-callback-function https://stackoverflow.com/questions/6847697/how-to-return-va...). You can surely find more, this is what distinguishes constructions like "callbacks" from "hooks" (which often return booleans, but may modify internal state passed to them or execute side effects as a callback) and further from "Promises" (which compute a value once and allow useful synchronization on the completion of that computation).
> Either that, or async/await is more powerful than callbacks, because most of the `async` functions I've seen have a return value (coroutines can and do yield results, and async/await is a way of implementing coroutines).
Well of course they are. I don't think I said they were equal in every respect, did I? I was a bit overly specific in talking about how Promises are often just used as callbacks, so sorry if I was unclear.
Async-await is a continuation monad. That's strictly a more powerful construction than a side-effect-only callback.
> I also don't really think that this solves the same issue as multiline lambdas in all cases.
I agree. It solves one very small slice: not having multi-line lambdas for filters and maps, nor a compiler that can fuse them.
> But multiline lambdas don't particularly clean up `if (x := re.match(...)): process(x)`. Which I'd argue is the more motivating example.
This PEP is even more exquisitely awful if that is truly the dominate use case. "We saved a line for the sake of saving a line" is a brutally frivolous reason to introduce that much new machinery.
- joshuamorton 8y ago>Async "callbacks" in Javascript do not have return semantically meaningful values. Async callbacks in javascript cannot return semantically meaningful values to sync code. But the classic "callback hell" is when you have async code calling other async code. In that case, a callback can absolutely return a meaningful value to the other async callback. And yes, that is a common and valid use. >This PEP is even more exquisitely awful if that is truly the dominate use case. I don't particularly disagree with you here.
- KirinDave 8y ago> But the classic "callback hell" is when you have async code calling other async code. In that case, a callback can absolutely return a meaningful value to the other async callback. But then it ceases to be a callback? It's a one-shot function called within the context of a callback. A use case promises are particularly good at enabling.
- joshuamorton 8y ago>But then it ceases to be a callback? No, it is a synchronous callback called in an async context. I think the confusion here is that you think that "callback" and "asynchronous callback" are synonyms when they are not[1]. A callback is simply any function passed into another function to be executed at a later time. An async callback is such a function which will be called asynchronously. In JS, asynchronous callbacks are not allowed to return values (or well they can return values they just cannot be meaningfully accessed). Synchronous callbacks, however, certainly are. Yes indeed, promises are incredibly good at un-nesting said synchronous-inside-of-asynchronous code. [1]: https://en.wikipedia.org/wiki/Callback_(computer_programming) https://en.wikipedia.org/wiki/Callback_(computer_programming...
- KirinDave 8y agoCan you show me an example of a "synchronous callback" in JavaScript code that is labeled as such in open source code? Because generally what I call those is "higher order functions." For example, by the definition you've offered Array.map takes a "synchronous callback" and that seems quite wrong.
- joshuamorton 8y agoDo the MDN docs count? > The then() method returns a Promise. It takes up to two arguments: callback functions for the success and failure cases of the Promise. Both of these functions may be synchronous, and may return values. Thus Promise.resolve(2) .then(x => x + 1) .then(x => x + 1) .then(console.log); Will print 4, not undefined. The documentation also refers to these as "handler" functions, but uses "callback" interchangeably, although less often. Generally speaking, "callback" is only used in the context of the function being executed in an async context, but again there's nothing stopping a sync code from being executed in an async context, and indeed this is pretty common (anytime one invokes a promise, as a simple example). [1]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/then https://developer.mozilla.org/en-US/docs/Web/JavaScript/Refe...