> You've provided examples and said that it violates design and fundamental
elements, but not which design and fundamentals, ie, the evidence for the
decision. I would expect more than "because I said so" for such a huge
language feature, but rather arguments grounded in computer science.


He very explicitly described the issue, in objective terms: a breach of
agreement in the context of the invocation of a foreign interface.

In simpler terms, you can't and should not be able to mess with the
internals of code you didn't write: this is similar to the principle of
encapsulation in OOP, where you cannot modify private properties of an
object.

Cancellation should be part of the contract of an async function: it is
safe, and most async languages already implement it explicitly by passing a
context or a cancellation token, the current approach of the RFC does it
implicitly, which is also fine.

Awaiting for the completion of spawned coroutines should *not* be part of
the contract of an async function: it is an incredibly easy footgun, as
it's incredibly easy to spawn a coroutine meant to i.e. run until the
object is destroyed, and then encounter a deadlock when the linked scope is
awaited for before the object is destroyed (even messier if cycles and thus
the GC are involved).

Languages like Kotlin that do implement await on scopes have already
realized that it is a mistake, as can be seen by the many warnings against
using await on a scope, as I already linked in previous emails.

On the other hand, making the same mistake described above, by cancelling a
scope, will produce a very easy to debug exception instead of a deadlock,
easily fixable by (warning the author of the library class) to use a new
scope to spawn coroutines within the object.

Awaiting a scope leads to deadlocks in case where a separate scope is
needed but not used, cancelling them leads to a simple exception.
Awaiting on multiple tasks can already be done, explicitly, with TaskGroup.


Regards,
Daniil Gentili.

Reply via email to