SE-0298: Async/Await: Sequences

@johannesweiss I'm not sure why you are shocked. You are extrapolating extremely general advice from a different language to a very specific situation (the design of a cancel() member) in Swift. Also, I didn't say you are completely wrong, only that the approach isn't super helpful -- that is why I argued for first principles thinking.

I will explain what I mean, but if you are specifically interested in making general claims about Swift than talking about the design of the cancel() feature, then I think it would be best taken to a different thread.

ARC will release the iterator eagerly for any reasonable use-case when you are done with them, and is 100% guaranteed to do so with the for-in syntax in particular. These are not general object graphs were are talking about in an overly heavy OO system, this is an iterator object which is a value.

You have correctly observed that iterators can be captured and escaped by closures, and doing so would make their lifetime less predictable. However, this isn't the basis of the guidance you are quoting, I don't think it is very common, and there are well known ways to solve that problem when they occur in practice. Even more concerning, "solving" this for AsyncIterator would imply that we should apply this pattern to effectively every other protocol (including e.g. Iterator) since there is nothing AsyncIterator specific about this problem -- many protocols implementations can indirectly refer to "expensive resources".

I can't see how "order of release" calls is relevant or has any problematic effects for the discussion at hand. You cannot destroy the sequence before the iterator, nor would the sequence have a pointer back to its iterator.

Are you making a claim about swift in general or are you trying to constructively contribute to the point of this discussion: iterators over async sequences? While the observation above is correct in the abstract, it is not particularly useful here unless you think that iterators need special defensive work to keep them from escaping out, per the points I made above.

We are talking about AsyncIterator iterator instances, none of which have been written yet, not making generic claims about Swift types overall. There exist no autoreleased implementations of AsyncIterator, this is 100% true.

This is a key stated goal of the Swift Concurrency direction and the core team has already said that they will revised older accepted proposals if necessary as the overall design evolves.


One of the things I observed in the pitch thread is that the cancel() design is both unnecessary (as observed above) but also that it is equivalent to the manual "invalidate" pattern used in GC systems to avoid finalizers (xref reference on finalize and an explanation). Not having finalizers (and the many problems they bring with them) in ARC and Swift is a huge progression over other GC'd languages. Bringing the manual reclamation patterns they require into Swift will cause exactly this sort of confusion (and has other issues like making AsyncIterator inconsistent with Iterator, etc). The only rationale to add it as part of this proposal is because we do not yet have linear types in Swift, which makes this a "point in time problem" not something inherent to the design of async sequences.

Here is the thing: ARC is not unreliable like GC'd systems, and I don't think we want finalizer like patterns in Swift API design. This is not a precedent that we want to set or encourage. Swift's gentle encouragement of people to use value types instead of reference types is one of the ways we directly improve this vs Objective-C, but there are many others as well. This significantly reduces the problem in practice, but does not completely invalidate @johannesweiss concern. We should aspire to keep improving the language (as already planned) instead of just go back to old GC patterns.

This is one of the reasons that I'm not in favor of adding the cancel() member. It has demonstrably created confusion in this thread, and we don't want people to pull forward this design into other places.

-Chris

13 Likes