config derivation with ZIO config and Magnolia
Config derivation with ZIO config and Magnolia.
Config derivation with ZIO config and Magnolia.
With simple ZIO layer creation, it’s convenient to use +`, `>>>` and `>>
to compose layers.
When layers and dependencies get more complex, ZLayer.make is there to help.
We’ll compare some code written with Either with similar code written using Exceptions and see how they are the same and how they differ.
In a previous post I’ve shown how to build a minimal example of a random case class generator using the metaprogramming features of Scala 3. While investigating this topic, I naturally came upon multiple ways to do this. In this post I will elaborate on two other ways to build the same generator and pick my personal favorite.
Coming from a Java background, reflection to me was a useful, albeit highly advanced tool in daily work. Being mostly used in libraries and frameworks, understanding its possibilities and usages was usually enough for me.
While advancing my career and moving to the scala ecosystem I learned about the existence of macros as a kind of compile-time reflection, used mostly by libraries. Still, it being a highly advanced language feature and not very ergonomic for daily programming, I felt more comfortable in the regular code world.
Then, during the development of a certain feature for the client I was working at, I felt the code I had written was so much boilerplate, there should be a way to shorten what I’ve written (unfortunately I cannot remember exactly what that was about, but it definitely had to do with some kind of mapping between data and their corresponding case classes…). In Java I would have tried my hand at reflection to extract and generate POJO’s, which could be done in scala as well, but I’ve always felt reflection isn’t the right tool for custom written production code, it being a slow, purely runtime process, which is never optimized by the compiler. I asked a senior colleague if using a macro to extract the field names and values would be a way to solve this, since it would bring me some compile-time safety. He then introduced me to the shapeless library, and the rabbit-hole opened up.
Preferable you start a ZIO application with just one runtime.unsafeRun
.
But when you’re migrating an old application to ZIO, you likely have multiple places to do runtime.unsafeRun
.
We will investigate how to deal with the environment (layers).
We’ll look at some examples of different kinds of exceptions and how we can deal with them in ZIO.
In a previous post I’ve shown how to use ZIO environments to provide your program with dependencies, or modules. While using environments at the customer I’m currently working for, we found out that the logic to get a database session object using a module would run over and again. This makes sense, since a ZIO[R, E, A] is a prescribed way of getting an A, and the result is not cached. Our application was reading configuration files and creating SQL sessions on every module call, while the resulting object was obviously constructed from the same underlying values. There are multiple ways to solve this:
Creating the singleton objects before running you application logic.
Caching the result of the loading code in a reference.
In this post I’ve chosen the latter, because I wanted to show the use of ZIO’s Ref
. Also, I like how semantically the desired data and the logic of retrieving it belong together.
ZIO is a type-safe, composable library for asynchronous and concurrent programming in Scala (from: The ZIO github). The library copes with functional IO, like many Functional Programming libraries do. The added value of ZIO is that the ZIO[R, E, A]
type-constructor
(the main IO monad of the library) acts as an IO monad, an error handling monad, and a reader monad. A functional programming style often needs a combination of these three types to cope with the most common problems when creating an application:
performing side effects (getting the A
)
coping with errors (handling E
)
supplying dependencies (providing R
)
This blogpost will show you how to cope with the R
part of a ZIO[R, E, A]
: the Environment
ZIO is a type-safe, composable library for asynchronous and concurrent programming in Scala (from: The ZIO github). The ZIO framework provides your program as immutable and pure values, which are very simple to properly unit test. But how can you run an integration test to see if your application starts up properly?
ScalaDays 2019 is alweer een week voorbij, maar langzaam, maar zeker krijgt de enorme hoeveelheid hoge-kwaliteit input hun gevolgen in mijn kennis over Scala.
Naar aanleiding van een rode draad die ik vond tijdens deze ScalaDays, heb ik enige gedachten over het gebruik van Types in Scala geblogd.
One of the coolest things a standard Scala install will give you, is the Scala interpreter. Technically speaking, this is not an interpreter. In the background, each statement is quickly compiled into bytecode and executed on the jvm. Therefore, most people refer to it as the Scala REPL: Read-Evaluate-Print-Loop. You can access it by starting a command shell on your system and typing in 'scala'. Do make sure your either run it from the place where scala is installed or have scala on your environment PATH. By using the repl, you can quickly experiment and test out different statements. Once you press ENTER it will evaluate the statement and display the result. Frequently you want to execute multi-line statements and luckily the repl has a solution for that. Simply type in :paste and the repl will accept multiline statements. To exit this mode and evaluate your code, simply type CTRL+D. Example:
$ scala
Welcome to Scala version 2.11.4 (Java HotSpot(TM) Client VM, Java 1.7.0\_75).
Type in expressions to have them evaluated.
Type :help for more information.
scala> :paste
// Entering paste mode (ctrl-D to finish)
class Camera {
//this is a multiline example in the REPL
val brand:String = "Canon"
val model:String = "5D mark III"
}
// Exiting paste mode, now interpreting.
defined class Camera
scala> val cam = new Camera
cam: Camera = Camera@bfd117
scala> cam.brand
res0: String = Canon