On Thu, Oct 16, 2025, at 09:38, Daniil Gentili wrote:
>
> > 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.
Hey Daniil and Edmond,
I think I understand the intention. Would it be better to instead of having ->awaitCompletion
(which feels like an implicit implementation of Awaitable without an explicit implmentation -- which
is the part that was bothering me), maybe having something like ->joinAll() or
->joinOnCancellation()? That way someone like me won't come along and wrap them in an
Awaitable because it looks Awaitable.
It also might be a good idea to make specifying a timeout in ms mandatory, instead of a taking an
Awaitable/Cancellation. This would also prevent people from simply passing a "never
returning" Awaitable thinking they're being clever.
It also might be good to provide a realistic looking example showing a "bad case" of how
this is dangerous instead of simply saying that it is, showing how a scope is not a
'future', but a container, and preemptively mention TaskGroups, linking to the future
scope (which it should also probably be listed there as well).
— Rob