Live data from Hacker News

Async/Await will make code simpler

blog.patricktriest.com

11–20 of 93 posts

Re: Async/Await will make code simpler

#12
I heard Doug Crockford talk about how he doesn't think async/await is that great an idea on a podcast a while ago.

His argument was that it's an unclean abstraction - it gives you access to 'features' of synchronous imperative syntax (lines in a function always execute in order, try-catch blocks, etc) but it remains conceptually and literally promises all the way down.

Therefore, all await 'calls' are really non-blocking at a global level, yet they appear blocking to the local lines of code inside the same async function. This is liable to cause confusion - particularly for beginners or occasional visitors to JS who don't fully grok or have the concept of promises top of mind - but really for everyone.

I've used async/await a fair amount in production code now (with babel) and while it does make some code a bit cleaner, honestly it is often to the detriment of understanding it when you come back to that code it in a few weeks. I've made plenty of stupid mistakes where the two 'faces' of the abstraction don't marry up, and it's frustrating.

More and more I'm inclined to just use promises, even when I have the choice of async/await - call a spade a spade and get on with your day. The article talks about promise chains getting complex and hard to read. Well, if this is the case, maybe it's your code or logic flows in general that need to be cleaned up, and changing the syntax to flatten the structures is actually just a sticky plaster over that.

Re: Async/Await will make code simpler

#13
post #7

Earlier quoted context omitted.

await/promises/etc mostly exist to solve the problem that JavaScript doesn't have threads so it can't wait for callbacks. About JavaScript, many other languages have had async/await for a long time. I have no idea why JS made such a huge deal of promises, I guess they're better than the callback hell before. Of course, in most languages using async isn't nearly as important for performance because they have thread po…

Node has threads in C++ for that sort of thing. Async programming is a big deal for performance. That's essentially the main reason Node is any faster than Python. If you use fully async Python on uvloop, you can get comparable performance.

It is ultimately a failure of language and runtime that programmer has to manually specify where he wants to make asynchronous vs. synchronous functions to get the optimal performance.

This blog posts elaborates on that better then I could do here, so I'm just going to link to it: http://journal.stuffwithstuff.com/2015/02/01/what-color-is-y...

Re: Async/Await will make code simpler

#14
post #3

same example with async control flow library and node style callback conventions function getUserInfo(callback) { async.parallel([api.getUser, api.getFriends, api.getPhoto], callback) }

Even with a library like async there will be so much boilerplate, since you need to handle (or pass) errors every step of the way.

With async/await you only need to deal with errors at the level you actually care about them (using the language build in try/catch block).

Re: Async/Await will make code simpler

#15
post #2

I go back and forth on async/await. On the one hand, it is utterly brilliant. On the other hand, it seems like the final epicycle, trying to fit a theory of circular geocentric orbits (call/return) onto a real world of elliptical heliocentric ones (asynchronous programming). So yes, it will make code easier, but I fear that will only serve to prolong the dominance of what is arguably the wrong programming model/archi…

await/promises/etc mostly exist to solve the problem that JavaScript doesn't have threads so it can't wait for callbacks. About JavaScript, many other languages have had async/await for a long time. I have no idea why JS made such a huge deal of promises, I guess they're better than the callback hell before. Of course, in most languages using async isn't nearly as important for performance because they have thread po…

await/promises/etc mostly exist to solve the problem that JavaScript doesn't have threads

async/await was popularized in C#, which does have threads.

Re: Async/Await will make code simpler

#16
post #2

I go back and forth on async/await. On the one hand, it is utterly brilliant. On the other hand, it seems like the final epicycle, trying to fit a theory of circular geocentric orbits (call/return) onto a real world of elliptical heliocentric ones (asynchronous programming). So yes, it will make code easier, but I fear that will only serve to prolong the dominance of what is arguably the wrong programming model/archi…

The way I look at it is as just another way of manipulating continuations, alongside conditional, loops, call/return, generators, coroutines, exceptions, etc. Even in some other hypothetical asynchronous paradigm, all those patterns still occur all over the place, so making them all composable with each other is a win. (Credit to http://blog.paralleluniverse.co/2015/08/07/scoped-continuati... for describing it this way.)

The surface syntax could maybe use some work- maybe make functions generic across asynchronicity, maybe swap `await` to being the default and explicitly mark the case where you want a reified Promise instead, etc. But in the end it's another valuable control structure.

Re: Async/Await will make code simpler

#18
post #9
post #4

Though the article doesn't mention it, the "alternative" is Reactive programming (via RxJS) I think for the typical UI application developer, async / await can provide easier readability and debugging, but at the cost of some expressive power and conciseness. Now that chrome supports async / await in the debugger, it's almost certainly the best choice, compared to promises and callbacks. In the redux world, you can s…

Only downside I've found with this is that Observables feel like more of a pain to test, since your logic gets more tightly coupled to your I/O. Or at least there's more complexity involved in the relationship between I/O and data manipulation. I used them for a Node project via RxJS and ended up just switching back to promises, as it wasn't complex enough of a project to really see much of a benefit from Observables…

Along with that, generators (redux-saga) are amazingly simple to test.

Re: Async/Await will make code simpler

#19

I heard Doug Crockford talk about how he doesn't think async/await is that great an idea on a podcast a while ago. His argument was that it's an unclean abstraction - it gives you access to 'features' of synchronous imperative syntax (lines in a function always execute in order, try-catch blocks, etc) but it remains conceptually and literally promises all the way down. Therefore, all await 'calls' are really non-bloc…

> I've made plenty of stupid mistakes where the two 'faces' of the abstraction don't marry up, and it's frustrating.

Would you mind sharing any of these?

Re: Async/Await will make code simpler

#20

I heard Doug Crockford talk about how he doesn't think async/await is that great an idea on a podcast a while ago. His argument was that it's an unclean abstraction - it gives you access to 'features' of synchronous imperative syntax (lines in a function always execute in order, try-catch blocks, etc) but it remains conceptually and literally promises all the way down. Therefore, all await 'calls' are really non-bloc…

Here's a great article somebody posted on HN awhile back, "What Color is Your Function?"

-- http://journal.stuffwithstuff.com/2015/02/01/what-color-is-y...

The proper abstraction is threads--i.e. a stack structure used for the storage of temporary values, which is shared by nested function invocations as well as similar structured programming constructs like if/else conditionals that together represent a singular thread of control through the program as it processes data and events. "Thread of control" is precisely what you're cobbling together with promises, async/await, etc, using clunky compiler constructs bolted onto the language model and implementation. The problem is that we conflate the implementation with the abstraction, sometimes by necessity (the legacy of the contiguous, so-called "C stack") but usually unnecessarily.

It pays to remember that some operating systems, such as some of IBM's mainframe platforms, IIRC, implement a thread stack as a linked-list of invocation frames, rather than a contiguous array. But it's completely transparent, as it should be. Async/await does the exact same thing, except it's not transparent as it should be. So now you have _two_ distinct, mutually incompatible kinds of functions solely because the implementation is unable to properly hide the gory details, which is ludicrous on its face.

Post reply on HN