This is interesting! It potentially addresses two concerns I had in the pitch phase:
1. Passing async lets as futures/promises
The answer might look like this:
@Future let thinger = { ... }
someHelper($thinger) // passes a future; someHelper won’t block on thinger
// unless it needs the value
func someHelper(_ thinger: Future<Thinger>) { ... }
2. Mixing “async lets” with manually created child tasks
Here’s a start of a solution to that:
return try await withThrowingTaskGroup(of: ??????????) { group in
for n in 0..<veggieCount {
group.async {
CookingTask.veggies(try await chopVegetables(n))
}
}
@Future(group: group) let meat = { await marinateMeat() } // tying async/future variable to a specific group
@Future(group: group) let oven = { await preheatOven() }
// …but wait, how do we get the veggies out?
// What is the result type of this task group? Hmmmmm.
}
So not a solution, not quite, but at least a design space for one.
(Not proposing discussion of either of these; just saying that the property wrapper approach opens up future directions in a nice way.)