I ask because I remember when trying to learn Kotlin, the docs made a big deal of structured concurrency[0], and golang of course is known for its concurrency story.
[0] https://kotlinlang.org/docs/coroutines-basics.html#structure...
I ask because I remember when trying to learn Kotlin, the docs made a big deal of structured concurrency[0], and golang of course is known for its concurrency story.
[0] https://kotlinlang.org/docs/coroutines-basics.html#structure...
In short, this means that thread pools and async runtimes cannot use this feature to provide borrowing across tasks. We're still stuck with Arc-ing everything that crosses task boundaries.
Prior to 1.0, there were "true" scoped threads (with a lifetime 'a on the join handle), which let you borrow from the parent thread. (This could have extended to tasks as well, had they been around.) unfortunately it wasn't safe together with the much more popular Arc/Rc, which wasn't 'static restricted, despite it's ability to cause cycles and leak. So those powerful scoped threads were removed and "destructors are not guaranteed to run in safe Rust" was formalized instead.
Seeing how popular async became, I wonder if this was the only and right way to move forward. I'm not against Arcs, they have their place. But if you can use normal RAII it's much preferable.
They can't use this function, but with some duplicated unsafe code they can still provide similar APIs for their callers, right? Things like this: https://github.com/jaboatman/tokio-scoped
That said, taking a step back it has crossed my mind that bringing back true scoping with unsafe in the impl might be an acceptable way forward, despite how upsetting this is to a lot of rustaceans. I think that the failure modes (ie triggering UB) for this case can be simply enumerated in a short list of "DON'Ts" (such as putting a scoped join handle in an Arc).
OTOH, since leaking was formalized and explicitly allowed (heck, even borderline encouraged through mem::forget), god knows if people have exploited that for other cases in true Hyrum's law fashion, that breaks the abovementioned idea. They certainly had the right to.
In the original acception I think you could literally do that, a scoped thread would just be a normal RAII object with various lifetime bounds.
With the new scoped threads, I’d think you need to create the scope in a and pass the scope handle to b so it can spawn the thread correctly.
For Rust it allows thread to play better with lifetimes, which means there are scenarios where you don’t need the overhead of a lock (and usually the Arc that does with it, unless you go with a global) or queue, you can just work with on-stack “unsynchronised” borrows and it’s thread safe.
That means lower syntactic and runtime overhead in the cases where it’s an option.
It was already available in crossbeam so it’s not novel novel, but not needing a dependency for it is useful still.