I completely agree with all of this. The thing is that this is exactly what Cats and Cats Effect do. They have answers for this (e.g. rewrite foreach
as traverse
), but without making the transformation entirely dependent on Cats Effect, it’s difficult or impossible to come up with any reliable answer here. It’s the same problem as for
-comprehensions, which are treated as a purely syntactic transformation, but that in turn denies them access to the pure
function and the knowledge that map(id) <-> id
, which in turn gives rise to most of the warts (withFilter
et al).
Note that I’m not saying that for
-comprehensions should become dependent on cats.Monad
, just that if they were, then they would be a lot more reliable at what they do. Similarly, if -Xasync
were dependent on Cats Effect, it would have a reliable answer to Li Haoyi’s concerns, but since it isn’t (and it shouldn’t be), these concerns are 100% valid and real.
As an aside, it’s worth noting for anyone considering it that building -Xasync
(or Monadless) with a dependency on Cats Effect would actually rule out Future
itself, since Future
doesn’t form a lawful monad, and the ways in which it is unlawful are extremely visible to users and amplified by something like -Xasync
, particularly if you attempt to solve the higher-order function problem.
tldr it’s all a mess.