Why can async let variables not be used on the RHS of boolean operators?
async let first: Int[] = someAsyncCall()
async let second: Int[] = anotherAsyncCall()
let bothEmpty = (await first).isEmpty && (await second).isEmpty
// or
let bothEmpty = await (first.isEmpty && second.isEmpty)
// or any other variation I can think of
I always get the errors
'async let' in an autoclosure that does not support concurrency
Capturing 'async let' variables is not supported
I know that && and || use @autoclosure to implement short-circuit evaluation, but the error is rather opaque; I couldn't find good information on either one on Google.
What's a good way to work around this? Do I have to use an explicit task group?
As you noted, Boolean operators are defined with the rhs parameter marked as an autoclosure, which means that the expression on the right-hand side is automatically bundled up into a closure, delaying its execution until necessary. Notably, this rhs closure property isn't marked as async ,so no await statements can appear "inside" it.
As for a workaround — you should be able to put both into an array and test them at the same time:
let bothEmpty = await [first, second].allSatisfy(\.isEmpty)
While that does get rid of one of the errors, it still complains about capturing the async let variable. In fact, I couldn't find any overload of && that would definitely work. Making the second argument of type Bool would shadow the standard library operator. This: