News for hackers. Stuff that matters.
Re:Unravelling `Async for` Loops by benatkin on Tuesday September 14, 2021 @09:17PM (#28533934)
I love for await and async for but I can't seem to figure out whether it's going to be easy to understand for beginning programmers. Any thoughts?
Re:Unravelling `Async for` Loops by enragedcacti on Tuesday September 14, 2021 @09:45PM (#28534194)
as someone who has written a lot of python but doesn't really work in the backend/services world, async itself felt like a huge mess to figure out when I was exposed to it while mucking around in FastAPI internals to prove out an idea. This was mainly because of the infectious nature of async and the fact that the callback function I was passing up had to be synchronous while also calling async functions while the entire thing was running in an async loop. That meant I had to add a dependency just to call a damn function https://pypi.org/project/nest-asyncio/.

Rant over. `for await` and `async for` to me seem like a fairly natural extension once you understand async. I think the problem comes in where once you run into async the first time you are forced to fully grasp it (and potentially rewrite a ton of your code) to move forward which is really counter to the rest of the Python learning experience.

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

Re:Unravelling `Async for` Loops by option_greek on Wednesday September 15, 2021 @12:56AM (#28535412)
The infectious nature is crazy. They also jump between boundaries of libraries and projects through dependencies. Thanks to async, most libraries in Rust now force addition of tokio which in turn convert more libraries into async. There should be some kind of compatibility layer that lets non async functions call async without jumping through hoops. As it stands async is more infectious than T-virus and Covid.
Re:Unravelling `Async for` Loops by knuthsat on Wednesday September 15, 2021 @04:33AM (#28536678)
The infectious nature is just how things work with types. Imagine if you had to annotate a function with IO every time you do something that reaches for something else outside of the program. You would either design things differently so that IO usage is minimized or you would make everything infected by IO.

With Async, people are still figuring things out.

I've encountered a bunch of code bases that are polluted with async when a better design could have removed it completely.

Re:Unravelling `Async for` Loops by pharmakom on Wednesday September 15, 2021 @02:03AM (#28535763)
I don’t really see how “infectious” a sync can be solved in a reasonable way. The function is async, can we really pretend it’s not? If it must be used in a sync context then it can be turned into a blocking call explicitly. This is not possible in JS so I can see the argument there, although they are now making the top level async too!
Re:Unravelling `Async for` Loops by ekzhang on Tuesday September 14, 2021 @09:37PM (#28534126)
If you're looking for alternate ways of designing an asynchronous coroutine API, Zig (https://ziglang.org/) and Go (https://golang.org/) have different implementations which might be worth reading into. Both avoid special syntax in the common beginner case, until you know enough to correctly write concurrent code (then you need async in Zig, and goroutines in Go). :)
Re:Unravelling `Async for` Loops by jerf on Tuesday September 14, 2021 @09:46PM (#28534198)
Well, "easy" is a relative term, but I would say with good certainty that it is going to be a barrier for a lot of people, because it forms an inner platform with the host language: https://infogalactic.com/info/Inner-platform_effect

That is, there's the way to run one statement, then the next in the synchronously-colored portion of the language:

    oneStatement()
    thenTheNext()
then there's the way to run one statement, then the next in the inner-platform asynchronously-colored portion of the language:

    await oneStatement().andThen(theNext)
Or whatever spelling you locally like. One way to write the synchronously-colored for loop, one way to write the asynchronously-colored for loop, different ways to branch on error, different ways to handle exceptions, etc.

This does not, on its own, mean "async" is bad. It is a complicated decision with many pieces. But this particular aspect of it means that there will always be a barrier to a programmer encountering this for the first time, simply by virtue of adding a new dimension they have to constantly account for to constructs that they're still getting a handle on.

(Having languages that don't color this code different has its own tradeoffs, and its own challenges. One of which is precisely because there isn't the separate color in the language itself, it's much easier to blunder into problems without even realizing it! People posting "why is this code broken?" to /r/golang, getting the answer "it's a race condition", and then the poster replies back with basically "what's a race condition?" is at least an every-couple-of-months sort of thing. I don't think there's an easy way to introduce concurrency to new programmers, honestly.)