Live data from Hacker News

Asynchronous Everything (2015)

joeduffyblog.com

11–20 of 26 posts

Re: Asynchronous Everything (2015)

#11
post #2

Async will continue to look awkward until we drop explicit "await" on function calls. Awaiting should be the default. If I call "async foo()" then I get back a promise I can explicitly await, but there should be no semantic difference between calling a synchronous function or asynchronous without modifiers. Not only it makes it more consistent, but you can implement running a synchronous function into a separate thre…

Async/await is awkward (or has been in languages I've used it in), but I don't think it's because of the await.

It's because await foo(); (or however you write it) doesn't tend to act the same as a synchronous function, even though that's what you're asking for. Because you called an async function, even though you immediately await the results, now your function is async, and it cascades up the chain, but often you need to provide a non-async interface, so then you're really stuck.

Javascript has an inflexible execution model, so you kind of need to take what you can get, but I prefer an explicit threadish thing plus async messaging. In your thread, you can (async) message another thread (or spawn a thread with an initial message) and wait for a response when you're ready to block, which could be immediately... or just send the message and loop on incoming messages to react appropriately if you get a reply.

Re: Asynchronous Everything (2015)

#12
post #5
post #4

Earlier quoted context omitted.

Agreed. That's basically what Go does. All functions are async, calling functions does an implicit await, and the go keyword let's you spawn a task without await. (At least that's what semantically happens) This way you can write seemingly imperative blocking code, and have it work fully asynchronously. It's great, freeing, and avoids the function coloring problem. It's really the feature I miss most when writing oth…

Performance-oriented languages tend to have a strong type system which lets them know well ahead of time what function is being called, so I see no reason why what you describe can't be done there without performance overhead.

There is a presumption of some runtime behaviors in the Go language spec that makes me wonder here … details can be lifted into the type system but if we’re trying to eliminate overhead, can we do this without revisiting a lot of the issues we were trying to solve with interesting concurrency primitives?

Re: Asynchronous Everything (2015)

#14
post #2

Async will continue to look awkward until we drop explicit "await" on function calls. Awaiting should be the default. If I call "async foo()" then I get back a promise I can explicitly await, but there should be no semantic difference between calling a synchronous function or asynchronous without modifiers. Not only it makes it more consistent, but you can implement running a synchronous function into a separate thre…

I would also like awaiting to be the default, as I've been bitten more than a few times by forgetting to await.

It's tricky though -- if I assign the result of a function to a variable, should I immediately await? What if I'm creating a temporary to pass into Promise.all or Promise.race? Perhaps not-awaiting needs to be explicit? I'm not sure.

Re: Asynchronous Everything (2015)

#15
post #11
post #2

Async will continue to look awkward until we drop explicit "await" on function calls. Awaiting should be the default. If I call "async foo()" then I get back a promise I can explicitly await, but there should be no semantic difference between calling a synchronous function or asynchronous without modifiers. Not only it makes it more consistent, but you can implement running a synchronous function into a separate thre…

Async/await is awkward (or has been in languages I've used it in), but I don't think it's because of the await. It's because await foo(); (or however you write it) doesn't tend to act the same as a synchronous function, even though that's what you're asking for. Because you called an async function, even though you immediately await the results, now your function is async, and it cascades up the chain, but often you…

> It's because await foo(); (or however you write it) doesn't tend to act the same as a synchronous function, even though that's what you're asking for. Because you called an async function, even though you immediately await the results, now your function is async, and it cascades up the chain, but often you need to provide a non-async interface, so then you're really stuck.

As far as I'm aware of, this is pretty standard for language-level concurrency sugar. It's syntactically blocking in that it allows you to write code without callbacks/message handlers, but it's infectious up the call stack.

Re: Asynchronous Everything (2015)

#16
post #2

Async will continue to look awkward until we drop explicit "await" on function calls. Awaiting should be the default. If I call "async foo()" then I get back a promise I can explicitly await, but there should be no semantic difference between calling a synchronous function or asynchronous without modifiers. Not only it makes it more consistent, but you can implement running a synchronous function into a separate thre…

Isn’t this like saying Haskell’s monads are awkward and should be implicit?

Not necessarily; you can remove the cumbersome async/await syntax while still tracking concurrency/mutation/control effects with an effect system, which might come with effect inference.

Also, even without effect inference, implicit effects don't have to be wrong: Haskell has them (unsafePerformIO) as do other MLs, but they aren't used in normal programming and that's largely turned out fine.

Re: Asynchronous Everything (2015)

#18
post #14
post #2

Async will continue to look awkward until we drop explicit "await" on function calls. Awaiting should be the default. If I call "async foo()" then I get back a promise I can explicitly await, but there should be no semantic difference between calling a synchronous function or asynchronous without modifiers. Not only it makes it more consistent, but you can implement running a synchronous function into a separate thre…

I would also like awaiting to be the default, as I've been bitten more than a few times by forgetting to await. It's tricky though -- if I assign the result of a function to a variable, should I immediately await? What if I'm creating a temporary to pass into Promise.all or Promise.race? Perhaps not-awaiting needs to be explicit? I'm not sure.

Yes “async foo()” call would be gathering promises without waiting.

Re: Asynchronous Everything (2015)

#19
post #8
post #2

Async will continue to look awkward until we drop explicit "await" on function calls. Awaiting should be the default. If I call "async foo()" then I get back a promise I can explicitly await, but there should be no semantic difference between calling a synchronous function or asynchronous without modifiers. Not only it makes it more consistent, but you can implement running a synchronous function into a separate thre…

What you are describing is really “async-never.” And in fact, the programming model that async/await gives you is in fact, blocking. To the programmer, awaiting is no different from blocking a function. In practice though, async/await is a specific way to implement a blocking programming model with non-blocking internals. It basically breaks functions down into state machines so they can be executed incrementally. Th…

> What you are describing is really “async-never.” And in fact, the programming model that async/await gives you is in fact, blocking. To the programmer, awaiting is no different from blocking a function.

Not exactly, I rather proposed async calls are explicit, instead of blocking calls being explicit.

Most people have no problem with the APPEARANCE of blocking. They mind if it's actually blocking under the hood. It's normal that when you issue some HTTP request, for ex. you can't proceed processing the response until you get it. One way or another "you await" that moment.

Regarding whether it's free or not, I still don't quite understand the problem TBH. An event loop isn't a hard addition to any language.

The only thing I wonder about is stack fragmentation.

Re: Asynchronous Everything (2015)

#20
post #2

Async will continue to look awkward until we drop explicit "await" on function calls. Awaiting should be the default. If I call "async foo()" then I get back a promise I can explicitly await, but there should be no semantic difference between calling a synchronous function or asynchronous without modifiers. Not only it makes it more consistent, but you can implement running a synchronous function into a separate thre…

Why color functions at all? I think Project Loom is/will be the best way forward where blocking calls will be automagically turned to non-blocking.
Post reply on HN