I agree with most of @Karl's concerns, but I also think the warts are probably acceptable in a base-level API that most people will never use. The basic issue is that the TaskGroup closure has a throwingness and return type that are independent of those run by the actual subtasks. It's hard to see how type inference could be used to simplify this.
However, I'm puzzled as to why the obvious Foundation-level wrappers don't seem to be in evidence. I hope they're coming!
For example, here's the code originally cited by @Karl again:
What I'd like to write for this instead is:
func fetchThumbnails(for ids:[String]) async throws -> [String: UIImage] {
let pairs = ids.asyncMap { try await fetchOneThumbnail(withID: $0) }
return try await Dictionary(uniqueKeysWithValues: pairs)
}
Here, pairs
is presumably some kind of AsyncSequence
with element type (String, UIImage)
.
This code does exactly the same thing, but without all the clutter. It takes advantage of Swift's normal type inference and of rethrows
. It presumes an async-aware asyncMap
on Sequence
and AsyncSequence
-aware inits on standard types. The implementation is, conceptually, no more complicated than the original code. (At least to the extent I can envision it, but quite possibly, I'm overlooking something. )
This version has one additional advantage over the original in that asyncMap
can presumably avoid forking a separate async tasklet for each of the original ids at once. I doubt that you'd want to call the original code with thousands of ids. Even if there are no extra threads involved, it's still a lot of overhead, is it not?
I understand the desire to get the fundamentals nailed down first. But it's disconcerting to see robust async/await support already present in higher-level APIs and none yet in the basic types.
Yes, yes, the people, organizations, and procedures involved in implementing these APIs are entirely separate. Nevertheless, I would hate to see the formal release ship with the original code above as the recommended interface to TaskGroups for general use.