`for try await` ergonomics

In converting an existing codebase (not large, but with a variety of completion-handler-based asynchronicity strategies), I ran into a couple of ergonomic issues. I don't recall these being discussed during the pitch phase of Swift concurrency, so I'm offering them as ideas for general discussion here and in related forum threads.

I ran into the following scenario:

async let results = someAsyncThrowingSequence()
…
for try await let result in results {
    …
}

Sadly, that doesn't compile. What I had to write was:

for try await let result in try await results {
    …
}

Ugh! It looks like the compiler treats for try await as a single, compound keyword, so it doesn't mark the entire statement as having a suspension point as try await normally would.

Could this be regarded as a compiler bug, since it's the only statement I can think of that requires multiple try await incantations?

Additionally, the following syntax:

try await for let result in results {
    …
}

means something different to the compiler. Would it be safe to have the compiler interpret try await for as for try await, based on the type of the expression after the in, which would determine whether this is a synchronous or asynchronous for?

4 Likes