-
Notifications
You must be signed in to change notification settings - Fork 33
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Backcall operator / Do notation #1558
Comments
Isn't this just const promisify = fn => (...args) =>
new Promise((resolve, reject) =>
fn(...args, (result, error) => error == null ? resolve(result) : reject(error))
); |
@bbrk24
gets turned into
It can't be done in userland since it rearranges the order of statements in an expression, while maintaining the appearance of a normal control flow (direct-style). Await/async does this too, but backcalls are more general, since they move everything after the backcall into a callback, being passed into the function on the right side of the backcall operator. Here is another example
It turns the rest of the scope into a callback, which get passed into the right side of the backcall operator |
I'm still not sure I understand the point. Your initial motivating example still feels like it could just use
Your second example,
feels to me like a convoluted way to avoid saying As for the third example, I really don't see the point in saying |
I guess one interesting thing about backcalls, compared to That said, I'm not aware of many scenarios where callbacks are used in a synchronous fashion; they're mostly for asynchronous behavior. In that case, By the way, have you seen IcedCoffeeScript? I used to use it, back before ES gained promises and its own notion of await $.getJSON url, defer json
console.log json
↓↓↓
$.getJSON url, (json) ->
console.log json One nice thing here is it doesn't assume that the callback is an appended last argument: you can put it anywhere. It also supported loops and such: [playground] results = new Array(list.length)
await
for item, i in list
fetch item, defer results[i]
console.log results I liked it at the time, and it took me a while to understand and transition to promises and Another question: what APIs are you using that still use callbacks? I feel like most of them have transitioned to promises. One exception is |
|
This is a contrived example to show how to do callback-oriented code without await/async
You are absolutely correct. This is exactly await/async, except that it doesn't only work for Promises, but any callback that has the structure of a promise (monadic structures). Which means it can work for exceptions, promises, nullables, iterators, generators, coroutines, promises, and many other control-flow structures that wouldn't need to be added to the language itself. This means we could add powerful features in user-land and make them usable with this simple sugar syntax, without having to ask language developers to implement custom syntax for every feature. |
Yes, this lets you write code that uses continuations (callbacks) in direct-style, ie, in the sequential fashion that async/await allows. Backcall operator solves this for all constructs that can be built with continuations (iterators, async/await, streams, even request handlers) and would be a game changer for people who are actively building these constructs from scratch, like the Effect-TS guys, reactivex, old promise libraries, coroutine libraries, http libraries and etc. to have much more control and power over their code. |
the do notation is also universal in functional programming languages, which don't ever need to introduce custom syntax for things like await/async, exceptions, iterators, nullables, and more, since the do notation is sufficient for solving the legibility problem of monads (which encapsules almost all control flow constructs and much more) |
I feel like I am repeating myself here and I want to correctly transmit the WHY of do notation. Please help me out here if my explanations aren't what you guys are looking for. To summarize:
|
Can we get a backcall operator like in Livescript and Glean?
Gets converted into
This frees us from needing to ask the language developer to add features like await/async, try/catch, generators, etc...
And gives functional programmers and framework developers a whole new level of power without ruining the ergonomy of the framework (see: effect-ts).
I'd hope for a syntax which is not as unnatural as gleam or scala, and more to Roc and Idris which use the
!
suffix (allowing an easy suffix like!
also gives us?.
and any other type of chaining without devs having to implement it)The text was updated successfully, but these errors were encountered: