2 ms·
Maybe a better way I could phrase my concern would be whether the benefit to having the debate outweighs the cost, and what metrics Rust might keep track of tha
by yingw787 7y ago
Maybe a better way I could phrase my concern would be whether the benefit to having the debate outweighs the cost, and what metrics Rust might keep track of that inform what the cost may be at every stage of the discussion.
The debate will always make sense for some time, but after a while it may block discussion of other features the Rust team might like to have for a roadmap milestone. Maybe having two forks with a tiny subset of async/await implemented (with something like tracer bullet development) would give stakeholders useful information on what the implementation cost would look like, what testing coverage overhead would be, and other metrics that balance the theoretical with the practical.
As to the statement that async/await was a smaller part of grokking concurrency in a language, maybe a better blog post might be this one:
https://vorpus.org/blog/notes-on-structured-concurrency-or-go-statement-considered-harmful/#go-statement-considered-harmful https://vorpus.org/blog/notes-on-structured-concurrency-or-g...
Some helpful background: Python has the notion of a global interpreter lock (GIL), which prevents concurrent CPU-bound tasks in threads from being effectively parallelized in Python. As a result, most development of concurrent tasks are I/O-bound, or call some C/Fortran library where the GIL does not block CPU-bound tasks, or use a process pool. I don't think this should affect the discussion because I think the issues with concurrency he talks about don't care about what resource it's bound by, they may just be more evident with I/O-bound tasks or provide greater perspective.
So `njs` (a Python core developer) went and developed an async I/O library called `trio`, which has the concept of "nurseries", which is a container for dynamic tasks. Nursery exit will block on the dynamic tasks within exiting, in order to make sure that the concurrent tasks within can appear as a single black box to the outside world. I believe he was saying how the async/await feature in Python should be combined with other control flow primitives, because otherwise creating tasks that outlive the parent, error propagation, and resource cleanup may result in spaghetti behavior and spaghetti code. He also claims that clean control flow also results in new features that assume said control flow, which makes development more powerful. This goes back to my assertion that async/await isn't the end-all/be-all in terms of making concurrent code grokkable.
One quote from that blog post that mentions Rust and thread correctness (I'm not sure if it's outdated):
"""
Go statements break error handling. Like we discussed above, modern languages provide powerful tools like exceptions to help us make sure that errors are detected and propagated to the right place. But these tools depend on having a reliable concept of "the current code's caller". As soon as you spawn a task or register a callback, that concept is broken. As a result, every mainstream concurrency framework I know of simply gives up. If an error occurs in a background task, and you don't handle it manually, then the runtime just... drops it on the floor and crosses its fingers that it wasn't too important. If you're lucky it might print something on the console. (The only other software I've used that thinks "print something and keep going" is a good error handling strategy is grotty old Fortran libraries, but here we are.) Even Rust – the language voted Most Obsessed With Threading Correctness by its high school class – is guilty of this. If a background thread panics, Rust discards the error and hopes for the best.
"""