Content warning: heavy editorializing
Speaking personally: forEach
is a blight on Sequence
and I wish it didn’t exist. People use it arbitrarily instead of for…in
for no apparent good reason. Frequently the answer they give for why is “it’s swifty” or “it’s more functional”. No. Just use a for
loop.
forEach
certainly has its uses. I believe the original intent was to stick on the end of a long composed chain of operations i.e. myArray.lazy.map(foo).filter(bar).forEach
. This is reasonable… except often these long chains are a bad idea. Less experienced developers see them in code, try to replicate them, and then get tied up in knots with type mismatches. It would be far better for them to break the code up and see the individual types, but they can’t because of the chain. Maybe tooling could fix this but… does it need fixing? “Doctor doctor, it hurts when I compose too many things”. Well, don’t compose so much.
The main use I reach for in forEach
is debugging… it would be nice sometimes to be able to stick .forEach(print)
on the end of an expression. Unfortunately print
has default arguments which don’t work with point free style so you have to write { print($0) }
which kind of spoils the fun.
I think there’s another reason why forEach
on async sequence specifically isn’t a great idea and that’s that it obscures the awaiting done by it. Unlike with synchronous sequences you may find execution paused for a long time awaiting the next element, and a proper for
loop will make what is going on clearer in the debugger.
Anyway in conclusion sorry for the rant and please don’t add it, deprecate the one on Sequence
instead (this will not happen but I can dream).