Concurrent, a few things can happen:
Async, without using real concurrency (you write a scheduler for concurrent actions that does the interleaving). This is nice but not the main point
Concurrentto also be
Asyncto use the real implementation. But then if every
Async, why not
Concurrent <: Async(which is the current situation)? Well, because we'd like to take an
F[_]: Concurrentconstraint and know that we can have concurrent control flow, without also having the ability to do every possible effect ever (which
Async <: Syncimplies)
Blockersay that it shouldn't be passed implicitly (https://github.com/typelevel/cats-effect/blob/master/core/shared/src/main/scala/cats/effect/Blocker.scala#L31). What is the reason behind this recommendation? I used to pass it implicitly and haven't seen any obvious drawbacks so far.
implicitvalues should never hold state. The implications of this are pretty profound and far-reaching, and a lot of it comes from experience in violating this rule (and paying the price later). An analogous "best practice" is that you should never do something like
implicit def strToInt(s: String): Int = .... You certainly can do this, and it'll work sometimes, but you would reject any PR that introduced something like that, wouldn't you? Same thing with
Blockerwill bite you. I guess the best thing to look at is the frustrations that people often have around
ExecutionContexts in the
FlatMap+ the run loop essentially a trampoline?
implicitvalues should never hold state."
ContextShiftrather than removing it from
Aren't Pure/FlatMap + the run loop essentially a trampoline?
well, you need to introduce an async boundary (or more), and then the execution context essentially acts as a trampoline (which is why Future is stack safe, it submits all the time). However having a fully async boundary (i.e. an ExecutionContext submission) is heavyweight, you can build a lighter weight one (this is
trampolineEc in cats-effect).
The thing with stack-safety is that there are some corner cases (you will see comments in the cats-effect codebase like "we need to insert another async boundary here for stack-safety")