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")
Async, so my async there is not idempotent (which it has to be)