Skip to content

Instantly share code, notes, and snippets.

@mikearnaldi
Created November 14, 2021 17:31
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mikearnaldi/f0b2e660069d63f9a6225ed03ae4e7b0 to your computer and use it in GitHub Desktop.
Save mikearnaldi/f0b2e660069d63f9a6225ed03ae4e7b0 to your computer and use it in GitHub Desktop.
My answers to Jan Nasiadka on ZIO
  • What do you think about ZIO’s typed errors? How do you think they help to write better applications?

Having typed errors is fundamental in order to write code that takes care of handling the edge cases, if you don’t have type information when calling a specific effect you cannot know what you may need to handle. At the moment typed errors are still limited in usability by Scala’s capabilities of dealing with unions, namely in Scala 2 unions are represented as sealed traits and you are forced to have an AppError tree with beneath a hierarchy of errors instead with the advent of Scala 3 it will be possible to represent errors using unions getting rid of the need for a big tree of sealed traits.

  • What do you think are the advantages of ZIO’s Fibers over Threads, when writing concurrent applications?

Fibers are extremely lightweight compared to threads and in ZIO they provide even a more rich api and set of capabilities. One of the huge innovations that ZIO introduces is the concept of a fork scope and a supervision model that is able to preserve the fork-join identity, additionally ZIO’s runtime is very efficient in scheduling fibers across threads and it’s getting better and better with ZIO 2.0..

  • Do you think ZIO helps you to make code more testable? Why?

ZIO introduced a third type parameter to manage dynamic environment, with the environment capabilities ZIO has developed a fully fledged dependency injection mechanism that enables you to easily construct trees of dependencies for your application. The same capability can be used to mock services in test contexts.

  • What’s your experience with ZManaged? What problems do you think it helps with?

ZManaged is a type that focuses on composition of managed resources, you might think of a managed resource as the pair of acquire/release that you would have in a bracket operation. Isolating the focus on the acquire-release logic enables zio to provide a rich set of apis for composition of resources. Using managed, you can represent for example services that are dependent on connection pools that require safe cleanup.

  • What’s your experience with ZLayers? What problems do you think it helps with?

Similar to how ZManaged places the focus on composing managed resources ZLayer (called ZServiceBuilder in ZIO 2.0) places its focus on composing dependency trees, with layers you can specify how your services are supposed to be constructed individually and easily compose them together, the pain point of layers has always been scala’s inability to emit decent error messages when you are forgetting to provide some dependency or where you have a type mismatch, this pain point has been resolved using compiler macros to enable automatic construction of layers firstly in zio-magic that later got merged in core and it is part of ZIO 2.0.

  • An important characteristic of ZIO is compositionality, how do you think that helps when writing real-world applications?

Compositionality is not unique to ZIO it is the core essence of functional programming, in fact all of what we do in fp is to isolate behaviours in an orthogonal manner to enable higher composition. ZIO is very good at this and especially the idea to have a single base effect type that is contravariant in R (the environment) has been a design choice that resulted in an extremely well-composable system of modules.

  • Do you have experience with ZStreams? What problems do you think it helps with?

ZStream is another step of innovation in ZIO’s ecosystem. I won’t bother talking about streams in zio 1.0 because they are getting killed by one of the best implementations I’ve ever seen for multiple reasons. ZStream in ZIO 2.0 is based on the concept of a ZChannel, an idea inspired by Haskell’s conduit, a ZChannel can be thought of as, in simple terms, something that can consume inputs and produce outputs this designed enabled for a unified encoding of streams, sinks and transducers under the same umbrella. ZChannel has a similar execution design that ZIO has, in fact it is an initially encoded data-type with an interpreter called the ChannelExecutor which takes care of executing the channel logic in an optimal way from the perspective of memory allocation and speed. ZStream will become a foundational building block in many aspects of application and library development, it isn’t the case today yet because the prior implementation in ZIO 1.0 was not declared stable (in fact streams have been reinvented many times since before getting to the current state of the art).

  • What do you think about ZIO’s interruption model and how it helps with achieving global application efficiency?

ZIO’s interruption model is not only needed for efficiency, for that it is good but more importantly it is a core part of application design for correctness, in fact when you run your application you always want to respond properly to process interruption signals. Here by react properly I mean doing the hard thing, graceful shutdown of everything that is running (that may be millions of fibers) asynchronously and in the correct order (for example if you have an effect that is performing a database op in a transaction first the effect should be interrupted than the transaction rolled back and finally the connection to the database closed, all of this is out-of-the-box with ZIO).

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