cats-effect
cats-effect copied to clipboard
Emphasize programs-as-values in the documentation
Following an extensive discord discussion, it seems we can be better at teaching the program-as-values paradigm in the Cats Effect documentation, and that this should be given priority over concurrency concepts (which presumably build on that knowledge anyway).
Personally, it hadn't really struck me until that discussion that without an appreciation for flatMap
and friends, it can feel like the only way to get an A
out of IO[A]
and compose programs is by calling an unsafeRun*
method.
I think we should put a "Hello World" example at the very beginning of the documentation and call it "Hello Flatmap" or "Hello IO.Flatmap"
More extensive discussions today 😅
we can be better at teaching the program-as-values paradigm in the Cats Effect documentation, and that this should be given priority over concurrency concepts
Priority may be too strong here. @BalmungSan suggests (paraphrased in my own words) that starting from the main page we should be explicit about:
- the value of
IO
for practical, concurrent programming - that using
IO
successfully will involve adopting the mindset of the programs-as-values paradigm
Furthermore, the "Concepts" page would benefit from making use of the word "program" instead of "effect" in certain places. E.g. consider this line:
Cats Effect is all about making it possible to express effects as values.
https://typelevel.org/cats-effect/docs/concepts
One more thought about this: programs-as-values is not entirely foreign. IIUC a lambda is a sort of program-as-a-value, and any sort of streaming framework where you build-up/express a compute graph/flow before executing it is also a program-as-a-value. These sorts of APIs are very common and frequently mixed with impure code.
So perhaps the challenge with Cats Effect is that we essentially dictate that you write your entire program-as-a-value (with good reason), which forces the paradigm shift*. Notably, this means any state and resource management needs to happen under this paradigm, which is not something that "mixed" frameworks will provide you any experience with (as far I know).
* Alternatively, IO
could be used as a better Future
here and there in an impure program via various calls to unsafeRun*()
, without getting tangled with state allocation / sharing. After all IO
is a great way to express a concurrent computation. This wouldn't be forcing the paradigm shift.