I have these two functions (which compile without errors):
func hasLocalChanges() -> Bool {
return false
}
func hasRemoteChanges() async -> Bool {
return await Task{ true }.value
}
Now, let's say I want to introduce a third function which will look like this:
func hasChanges() async -> Bool {
return self.hasLocalChanges() || await self.hasRemoteChanges()
}
Then this function will give me a compiler error saying:
'async' call in an autoclosure that does not support concurrency
But why is that?
I can resolve the error by swapping the operands …
func hasChanges() async -> Bool {
return await self.hasRemoteChanges() || self.hasLocalChanges()
}
…, which, again, will make the code compile without errors.
But I really want to make use of lazy evaluation and have the asynchronous function be executed last. So the only way to achieve that would be to say …
func hasChanges() async -> Bool {
if !self.hasLocalChanges() {
return await self.hasRemoteChanges()
} else {
return true
}
}
…, which seems a little cumbersome.
Can anyone explain to me why I am getting that error in the first place?
EDIT:
Thanks a lot to @aciniglio:
One way to rewrite the code is like this (assuming the two functions are also allowed to throw):
func hasChanges() async throws -> Bool {
return try await hasLocalChanges().or(await hasRemoteChanges())
}
extension Bool {
func or(_ other: @autoclosure () async throws -> Bool) async rethrows -> Bool {
return self ? true : try await other()
}
}