You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
This repository was archived by the owner on Nov 14, 2024. It is now read-only.
Copy file name to clipboardExpand all lines: README.md
+1-1
Original file line number
Diff line number
Diff line change
@@ -16,7 +16,7 @@ The bundler will automatically update as you modify content.
16
16
17
17
All articles are in the `_posts` directory. To add a new article, create a new file with the name `yyyy-mm-dd-title-of-the-article.md`. Jekyll will use the date in the filename and the front matter (described shortly) to automatically sort articles and search by date.
18
18
19
-
All files are Markdown, with a header that looks like this (example from one of the articles):
19
+
All files are Markdown, with a header that looks like below (example from one of the articles). Just copy everything and change the title, tags and excerpt
Copy file name to clipboardExpand all lines: _drafts/2021-09-14-scalac.md
+1-1
Original file line number
Diff line number
Diff line change
@@ -68,7 +68,7 @@ Pattern matching is one Scala-specific feature that has been around for more tha
68
68
69
69
Learn what a pattern matching expression is and why it's useful. Deconstruct case classes and constants first, that will cover 90% of your use case in practice.
70
70
71
-
After that, if you have some spare time and you're ready to show off to your Scala teammates, learn some [nifty tricks](https://blog.rockthejvm.com/8-pm-tricks/) with pattern matching.
71
+
After that, if you have some spare time and you're ready to show off to your Scala teammates, learn some [nifty tricks](/8-pm-tricks/) with pattern matching.
72
72
73
73
At this point, you can be a productive Scala developer for simple to medium projects. The topics above are what I teach in my [Scala 3 Essentials](https://rockthejvm.com/p/scala) course on Rock the JVM, and you can also follow the above steps on your own to learn by yourself in just a day of focused work.
Copy file name to clipboardExpand all lines: _posts/2020-10-12-spark-broadcast-joins.md
+1-1
Original file line number
Diff line number
Diff line change
@@ -83,7 +83,7 @@ Brilliant - all is well. Except it takes a bloody ice age to run.
83
83
84
84
Why does the above join take so long to run?
85
85
86
-
If you ever want to debug performance problems with your Spark jobs, you'll need to know how to [read query plans](https://blog.rockthejvm.com/reading-query-plans/), and that's what we are going to do here as well. Let's have a look at this job's query plan so that we can see the operations Spark will perform as it's computing our innocent join:
86
+
If you ever want to debug performance problems with your Spark jobs, you'll need to know how to [read query plans](/reading-query-plans/), and that's what we are going to do here as well. Let's have a look at this job's query plan so that we can see the operations Spark will perform as it's computing our innocent join:
Copy file name to clipboardExpand all lines: _posts/2020-11-02-scala-3-indentation.md
+1-1
Original file line number
Diff line number
Diff line change
@@ -105,7 +105,7 @@ def computeMeaningOfLife(year: Int): Int =
105
105
106
106
This part may be particularly confusing. The way I like to talk about it is: imagine the compiler inserted braces between `=` and your returned value; in this way, the implementation of the method is a _code block_, which, obviously, is a single expression whose value is given by its last constituent expression. The significant indentation means, in this case, that we actually have an invisible code block there.
107
107
108
-
An indentation region is also created when we define classes, traits, objects or [enums](https://blog.rockthejvm.com/enums-scala-3/) followed by a colon `:` and a line break. This token is now interpreted by the compiler as "colon at end of line", which is to say "colon then define everything indented". Examples:
108
+
An indentation region is also created when we define classes, traits, objects or [enums](/enums-scala-3/) followed by a colon `:` and a line break. This token is now interpreted by the compiler as "colon at end of line", which is to say "colon then define everything indented". Examples:
**The routes defined using the http4s DSL are composable**. So, it means that we can define them in different modules and then compose them in a single `HttpRoutes[F]` object. As developers, we know how vital module compositionality is for code that is easily maintainable and evolvable.
240
240
241
-
The trick is that the type `HttpRoutes[F]`, being an instance of the `Kleisli` type, is also a [`Semigroup`](https://blog.rockthejvm.com/semigroups-and-monoids-in-scala/). In fact, it's a `SemigroupK`, as we have a semigroup of an effect (remember the `F[_]` type constructor).
241
+
The trick is that the type `HttpRoutes[F]`, being an instance of the `Kleisli` type, is also a [`Semigroup`](/semigroups-and-monoids-in-scala/). In fact, it's a `SemigroupK`, as we have a semigroup of an effect (remember the `F[_]` type constructor).
242
242
243
243
The main feature of semigroups is the definition of the `combine` function which, given two elements of the semigroup, returns a new element also belonging to the semigroup. For the `SemigroupK` type class, the function is called`combineK` or `<+>`.
244
244
@@ -335,7 +335,7 @@ The `sanitized` attribute may safely be displayed to a client to describe an err
335
335
336
336
Instead, the `leftMap` function comes as an extension method of the Cats `Bifunctor` type class. When the type class is instantiated for the `Either` type, it provides many useful methods as `leftMap`, which eventually applies the given function to a `Left` value.
337
337
338
-
Finally, the `OptionalValidatingQueryParamDecoderMatcher[T]` returns the result of the validation process as an instance of the type `Validated[E, A]`. [`Validated[E, A]`](https://blog.rockthejvm.com/idiomatic-error-handling-in-scala/#4-advanced-validated) is a type coming from the Cats library representing the result of a validation process: If the process ends successfully, the `Validated` contains instance of type `A`, errors of type `E` otherwise. Moreover, we use `Validated[E, A]` in opposition to `Either[E, A]`, for example, because it accumulates errors by design. In our example, the _matcher_ returns an instance of `Validated[ParseFailure, Year]`.
338
+
Finally, the `OptionalValidatingQueryParamDecoderMatcher[T]` returns the result of the validation process as an instance of the type `Validated[E, A]`. [`Validated[E, A]`](/idiomatic-error-handling-in-scala/#4-advanced-validated) is a type coming from the Cats library representing the result of a validation process: If the process ends successfully, the `Validated` contains instance of type `A`, errors of type `E` otherwise. Moreover, we use `Validated[E, A]` in opposition to `Either[E, A]`, for example, because it accumulates errors by design. In our example, the _matcher_ returns an instance of `Validated[ParseFailure, Year]`.
339
339
340
340
Once validated the query parameter, we can introduce the code handling the failure with a `BadRequest` HTTP status:
Copy file name to clipboardExpand all lines: _posts/2021-06-24-zio-fibers.md
+1-1
Original file line number
Diff line number
Diff line change
@@ -11,7 +11,7 @@ _Another great round by [Riccardo Cardin](https://github.com/rcardin), a proud s
11
11
12
12
_Enter Riccardo:_
13
13
14
-
Many libraries implement the effect pattern in the Scala ecosystem: Cats Effect, Monix, and ZIO, just to list some. Each of these implements its own concurrency model. For example. Cats Effect and ZIO both rely on _fibers_. In the articles [Cats Effect 3 - Introduction to Fibers](https://blog.rockthejvm.com/cats-effect-fibers/) and [Cats Effect 3 - Racing IOs](https://blog.rockthejvm.com/cats-effect-racing-fibers/), we introduced the fiber model adopted by the Cats Effect library. Now, it's time to analyze the ZIO library and its implementation of the fiber model.
14
+
Many libraries implement the effect pattern in the Scala ecosystem: Cats Effect, Monix, and ZIO, just to list some. Each of these implements its own concurrency model. For example. Cats Effect and ZIO both rely on _fibers_. In the articles [Cats Effect 3 - Introduction to Fibers](/cats-effect-fibers/) and [Cats Effect 3 - Racing IOs](/cats-effect-racing-fibers/), we introduced the fiber model adopted by the Cats Effect library. Now, it's time to analyze the ZIO library and its implementation of the fiber model.
Copy file name to clipboardExpand all lines: _posts/2021-08-19-zio-kafka.md
+3-3
Original file line number
Diff line number
Diff line change
@@ -19,7 +19,7 @@ So, let's proceed without further ado.
19
19
20
20
## 1. Background
21
21
22
-
Following this article will require a basic understanding of how Kafka works. Moreover, we should know what the effect pattern is and how ZIO implements it (refer to [ZIO: Introduction to Fibers](https://blog.rockthejvm.com/zio-fibers/), and to [Organizing Services with ZIO and ZLayers](https://blog.rockthejvm.com/structuring-services-with-zio-zlayer/) for further details).
22
+
Following this article will require a basic understanding of how Kafka works. Moreover, we should know what the effect pattern is and how ZIO implements it (refer to [ZIO: Introduction to Fibers](/zio-fibers/), and to [Organizing Services with ZIO and ZLayers](/structuring-services-with-zio-zlayer/) for further details).
23
23
24
24
Apache Kafka is the standard de-facto within messaging systems. **Every Kafka installation has a broker, or a cluster of brokers, which allows its clients to write and read messages in a structure called _topic_, which are essentially distributed queues**. The clients writing into topics are called _producers_, whereas _consumers_ read information from topics.
25
25
@@ -190,7 +190,7 @@ In this particular case, we obtain an instance of an `RManaged`, that in the ZIO
190
190
191
191
In fact, ZIO internally uses such a service to manage the connection pool to the broker for a consumer.
192
192
193
-
Last but not least, we create a `ZLayer` from the `managedConsumer`, allowing us to provide it as a service to any component depending on it (for a comprehensive introduction to the `ZLayer` type, please refer to the article [Organizing Services with ZIO and ZLayers](https://blog.rockthejvm.com/structuring-services-with-zio-zlayer/)):
193
+
Last but not least, we create a `ZLayer` from the `managedConsumer`, allowing us to provide it as a service to any component depending on it (for a comprehensive introduction to the `ZLayer` type, please refer to the article [Organizing Services with ZIO and ZLayers](/structuring-services-with-zio-zlayer/)):
194
194
195
195
```scala
196
196
val consumer: ZLayer[Clock with Blocking, Throwable, Consumer] =
@@ -641,7 +641,7 @@ Hence, the produced effect requests a `Producer[Any, UUID, Match]` as environmen
We can compose the production of the messages and the consumption directly in one program using _fibers_ (see [ZIO: Introduction to Fibers](https://blog.rockthejvm.com/zio-fibers/) for further details on ZIO fibers):
644
+
We can compose the production of the messages and the consumption directly in one program using _fibers_ (see [ZIO: Introduction to Fibers](/zio-fibers/) for further details on ZIO fibers):
Copy file name to clipboardExpand all lines: _posts/2021-10-21-kafka-streams.md
+2-2
Original file line number
Diff line number
Diff line change
@@ -54,7 +54,7 @@ import java.util.Properties
54
54
importscala.concurrent.duration._
55
55
```
56
56
57
-
We will use version 2.8.0 of Kafka. As we've done in the article [ZIO Kafka: A Practical Streaming Tutorial](https://blog.rockthejvm.com/zio-kafka/), we will start the Kafka broker using a Docker container, declared through a `docker-compose.yml` file:
57
+
We will use version 2.8.0 of Kafka. As we've done in the article [ZIO Kafka: A Practical Streaming Tutorial](/zio-kafka/), we will start the Kafka broker using a Docker container, declared through a `docker-compose.yml` file:
58
58
59
59
```yaml
60
60
version: '2'
@@ -186,7 +186,7 @@ If we want to create any structure on top of Kafka topics, such as stream, we ne
186
186
187
187
What's a `Serde`? The `Serde` word stands for `Serializer` and `Deserializer`. A `Serde` provides the logic to read and write a message from and to a Kafka topic.
188
188
189
-
So, if we have a `Serde[R]` instance, we can deserialize and serialize objects of the type `R`. In this article, we will use JSON format for the payload of Kafka messages. In Scala, one of the most used libraries to marshall and unmarshall JSON into objects is Circe. We already talked about Circe in the post [Unleashing the Power of HTTP Apis: The Http4s Library](https://blog.rockthejvm.com/http4s-tutorial/), when we used it together with the Http4s library.
189
+
So, if we have a `Serde[R]` instance, we can deserialize and serialize objects of the type `R`. In this article, we will use JSON format for the payload of Kafka messages. In Scala, one of the most used libraries to marshall and unmarshall JSON into objects is Circe. We already talked about Circe in the post [Unleashing the Power of HTTP Apis: The Http4s Library](/http4s-tutorial/), when we used it together with the Http4s library.
Copy file name to clipboardExpand all lines: _posts/2021-12-28-doobie.md
+5-5
Original file line number
Diff line number
Diff line change
@@ -62,7 +62,7 @@ The above configuration defines a Postgres instance listening on port 5432 and h
62
62
63
63
Moreover, we define an Adminer instance listening on port 8080. Adminer is a web interface to Postgres, which we will use to create a database, some tables, and populate them with some data.
64
64
65
-
Next, we need a use case to train our skills about Doobie. We will use the same use case we introduced in the article [Unleashing the Power of HTTP Apis: The Http4s Library](https://blog.rockthejvm.com/http4s-tutorial/), which is implementing a small IMDB-like web service. The primary domain objects of the service are movies, actors, and directors. The goal is to use Doobie to interact with these tables through queries, insertion, and updates.
65
+
Next, we need a use case to train our skills about Doobie. We will use the same use case we introduced in the article [Unleashing the Power of HTTP Apis: The Http4s Library](/http4s-tutorial/), which is implementing a small IMDB-like web service. The primary domain objects of the service are movies, actors, and directors. The goal is to use Doobie to interact with these tables through queries, insertion, and updates.
66
66
67
67
Inside Postgres, we will model the domain objects as tables and define their relations as foreign keys. The tables will be named `movies`, `actors`, and `directors`:
As it's the first query we make, the code is really verbose. However, we can analyze every aspect of a query in this way.
240
240
241
-
First, the `sql` [interpolator](https://blog.rockthejvm.com/how-to-create-your-own-string-interpolator/) allows us to create SQL statement fragments (more to come). Next, the method `query` lets us create a type that maps the single-row result of the query in a Scala type. The class is called `Query0[A]`. To accumulate results into a list, we use the `to[List]` method, which creates a `ConnectionIO[List[String]]`.
241
+
First, the `sql` [interpolator](/how-to-create-your-own-string-interpolator/) allows us to create SQL statement fragments (more to come). Next, the method `query` lets us create a type that maps the single-row result of the query in a Scala type. The class is called `Query0[A]`. To accumulate results into a list, we use the `to[List]` method, which creates a `ConnectionIO[List[String]]`.
242
242
243
243
The `ConnectionIO[A]` type is interesting since it introduces a typical pattern used in the Doobie library. In fact, **Doobie defines all its most essential types as instances of the [`Free` monad](https://typelevel.org/cats/datatypes/freemonad.html)**.
244
244
@@ -307,7 +307,7 @@ val actorsNamesStream: fs2.Stream[doobie.ConnectionIO, String] =
307
307
sql"select name from actors".query[String].stream
308
308
```
309
309
310
-
The `stream` method on the type `Query0` returns a `Stream[ConnectionIO, A]` which means a stream containing instances of type `A`, wrapped in an effect of type `ConnectionIO` (for a brief explanation of the Effect pattern, please refer to [The Effect Pattern](https://blog.rockthejvm.com/zio-fibers/#2-the-effect-pattern)).
310
+
The `stream` method on the type `Query0` returns a `Stream[ConnectionIO, A]` which means a stream containing instances of type `A`, wrapped in an effect of type `ConnectionIO` (for a brief explanation of the Effect pattern, please refer to [The Effect Pattern](/zio-fibers/#2-the-effect-pattern)).
311
311
312
312
Once we obtained an instance of a `Stream`, we can decide to return it to the caller as it is, or to compile it into a finite type, such as `List[String]` or `Vector[String]`:
In the example above, we build the three parts of the SQL statements, and then we combine them to produce the final query using the `++` operator. It's easy to understand why `Fragment` is also a `Monoid` since it's possible to use the `++` operator to define the `combine` function of monoids (more on the article [Semigroups and Monoids in Scala](https://blog.rockthejvm.com/semigroups-and-monoids-in-scala/)):
406
+
In the example above, we build the three parts of the SQL statements, and then we combine them to produce the final query using the `++` operator. It's easy to understand why `Fragment` is also a `Monoid` since it's possible to use the `++` operator to define the `combine` function of monoids (more on the article [Semigroups and Monoids in Scala](/semigroups-and-monoids-in-scala/)):
407
407
408
408
```scala
409
409
// Doobie library's code
@@ -615,7 +615,7 @@ Doobie defines the instances of the above type classes for the following types (
615
615
*`Instant`, `LocalDate`, `LocalTime`, `LocalDateTime`, `OffsetTime`, `OffsetDateTime` and `ZonedDateTime` from the `java.time` package; and
616
616
* single-element case classes wrapping one of the above types.
617
617
618
-
Deriving the `Get` and `Put` type classes for types that don't fit into one of the above categories is relatively easy. To create a concrete example, we introduce in our project the [estatico/scala-newtype](https://github.com/estatico/scala-newtype), which allows creating a new type that is a subtype of the original type but with a different name. The description of newtypes is far beyond the scope of this article, but you can find a good introduction on [Value Classes in Scala](https://blog.rockthejvm.com/value-classes/).
618
+
Deriving the `Get` and `Put` type classes for types that don't fit into one of the above categories is relatively easy. To create a concrete example, we introduce in our project the [estatico/scala-newtype](https://github.com/estatico/scala-newtype), which allows creating a new type that is a subtype of the original type but with a different name. The description of newtypes is far beyond the scope of this article, but you can find a good introduction on [Value Classes in Scala](/value-classes/).
619
619
620
620
First, let's create a newtype wrapper around an actor name:
Copy file name to clipboardExpand all lines: _posts/2022-02-10-fs2.md
+1-1
Original file line number
Diff line number
Diff line change
@@ -30,7 +30,7 @@ The `fs2-core` library provides the core functionalities of the library. Many ot
30
30
31
31
To work well with fs2, you'll need to be comfortable with Scala, of course. Some basics of Cats Effect would be wonderful. Rock the JVM has this in-depth [Cats Effect course](https://rockthejvm.com/p/cats-effect) if you're interested in mastering it, but it's not required.
32
32
33
-
It's usual for us at Rock the JVM to build the examples around a concrete scenario. We can continue to refer to the _myimdb_ project that we used both in the articles on [_http4s_](https://blog.rockthejvm.com/http4s-tutorial/) and on [_doobie_](https://blog.rockthejvm.com/doobie/).
33
+
It's usual for us at Rock the JVM to build the examples around a concrete scenario. We can continue to refer to the _myimdb_ project that we used both in the articles on [_http4s_](/http4s-tutorial/) and on [_doobie_](/doobie/).
34
34
35
35
So, we define the Scala class that represents an actor inside a hypothetical movie database:
0 commit comments