Skip to content

Instantly share code, notes, and snippets.

@kubukoz
Last active November 15, 2021 05:59
Show Gist options
  • Star 12 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save kubukoz/f32347ce711d65fb70752bb408f3d65c to your computer and use it in GitHub Desktop.
Save kubukoz/f32347ce711d65fb70752bb408f3d65c to your computer and use it in GitHub Desktop.

Why you prefer cats instead of zio? TF? It’s looks like zio ecosystem more widely and zio 2.0 has better performance What do you think?

Great question!

Performance-wise, it really depends on what you're doing. The problem with benchmarks (including the ones posted for ZIO and Cats Effect) is that they apply only to abstract situations, which are often nothing like what you see in real applications. A great write-up on this problem by Daniel Spiewak here, he wrote it better than I ever could: https://gist.github.com/djspiewak/f4cfc08e0827088f17032e0e9099d292

Also, this is not an app meant for production - I don't care that much about performance under load because there will be no load. And individual operations will often be bounded by I/O anyway, so the efficiency of the underlying runtime is likely not going to make a noticeable difference in use. Then again, both the client and server are JVM apps, so even the start-up penalty of the client will slow us down than picking even the least efficient effect system in existence.

Authors of ZIO may claim the performance is superior, but I can just as well provide a counterpoint - teams at my current company run applications both written with ZIO and with Cats Effect (2, 3) - all of them perform very well under global load (the scale of millions of requests per second) and a performance issue caused by a limitation/flaw of a runtime system is very rarely seen, if ever.

Then there's the 2.0 version you mentioned - it's barely a milestone release at this stage and I wouldn't recommend using it for anything serious yet. Many of the libraries haven't been released with support for that version, it can break binary compatibility as often as the authors want (milestones don't need to guarantee any compatibility), and thus the ecosystem is very limited in that version. I wouldn't want to have to reimplement libraries or submit pull requests to them just to have something that already exists in a stable version compatible with the alternative ecosystems (CE 2/3, or even ZIO 1).

Then, the maturity/adoption of the ecosystem itself - I don't think the ZIO ecosystem is used more widely than the Cats one. For obvious reasons, like companies trying to keep their secrets private, we'll never know exactly how much usage there is in the wild. Also, I don't currently consider the ZIO ecosystem to be mature - many features that are the norm in an ecosystem (JDBC interop/native clients for SQL databases like Postgres, configuration, logging, HTTP servers/clients) are implemented in only one library (giving little choice to the developer, which has upsides and downsides, but I consider it mostly a bad thing), which can barely be called mature (breaks compatibility often, has zero documentation, lacks important features, integrations, etc.)... or are available only through integration with other ecosystem (CE, monix, Future-land/akka etc.), which often defeats the point of using ZIO due to a fixed error type (Throwable) or forces non-idiomatic usage against the principles of using the Environment type parameter of ZIO[R, E, A].

GitHub stars don't equal a mature ecosystem.

You mentioned TF (Tagless Final) and yes, I still like that style and prefer it to the alternative proposed by ZIO - although I find the latter interesting and a good use of Scala's type system with regards to subtyping/variance, it has issues that sometimes make it even more complex than TF - type errors can be terribly difficult to understand (zio-magic / zio 2.0 macros make it nicer when wiring layers, but not in other contexts), types like ZQueue having 7 or more 1-letter type parameters, and so on.

Finally, call it personal preference, but seeing these, I prefer to spend an hour explaining F[_]: Alg and Kleisli[OptionT[F, *], Request[F], Response[F]] to each new team member. TF composes well, Typelevel libraries are stable, offer a variety of choices for most of the things I've seen it used for, and have great communities behind them (not saying the ZIO community isn't great, but there's been problems with the behavior of some of the leaders in the past, and it puts off many people from getting involved).

Cats Effect builds up on Cats Core, which has been binary compatible for almost FOUR years - in the Scala world that's really something. Cats Effect broke compat only after over 2 years, and the maintainers (myself included) made every effort to make the migration as seamless as possible, given the many changes to the APIs that were just necessary due to new insight and changes in the design.

I think it's a great, constantly growing ecosystem, and I'm happy to help make it even bigger, which is why I've invested so much of my free, unpaid time trying to explain the rough edges here and in some of my talks.

That's more or less why I'm sticking to Cats/TF for now :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment