diff --git a/_posts/2023-01-03-kotlin-coroutines-101.md b/_posts/2023-01-03-kotlin-coroutines-101.md index 34a5e1b5051d..aba616121231 100644 --- a/_posts/2023-01-03-kotlin-coroutines-101.md +++ b/_posts/2023-01-03-kotlin-coroutines-101.md @@ -13,7 +13,9 @@ _Enter Riccardo:_ This article introduces Kotlin coroutines, a powerful tool for asynchronous programming. Kotlin's coroutines fall under the umbrella of structured concurrency. They implement a model of concurrency which you can consider similar to Java virtual threads, [Cats Effect](https://blog.rockthejvm.com/cats-effect-fibers/) and [ZIO fibers](https://blog.rockthejvm.com/zio-fibers/). In detail, we'll present some use cases concerning the use of coroutines on backend services, not on the Android environment. -The article requires a minimum knowledge of the Kotlin language. Still, you should be fine if you come from a Scala background. +The article requires existing knowledge of Kotlin. + +> Coroutines can be tough. If you need to get the Kotlin fundamentals **fast** and with thousands of lines of code and a project under your belt, you'll love [Kotlin Essentials](https://rockthejvm.com/p/kotlin-essentials). It's a jam-packed course on **everything** you'll ever need to work with Kotlin for any platform (Android, native, backend, anything), including less-known techniques and language tricks that will make your dev life easier. Check it out [here](https://rockthejvm.com/p/kotlin-essentials). ## 1. Background and Setup @@ -838,6 +840,8 @@ The only exception to the context inheritance rule is the `Job` context instance Our journey through the basics of the Kotlin coroutines library is over. We saw why coroutines matter and made a simplified explanation of how they're implemented under the hood. Then, we showed how to create coroutines, also introducing the structural concurrency topic. We saw how cooperative scheduling and cancellation work with many examples. Finally, we introduced the main features of the coroutines' context. There is a lot more to say about coroutines, but we hope this article can be a good starting point for those who want to learn more about them. +If you found coroutines too difficult, you can quickly get the Kotlin basics you need by following the complete [Kotlin Essentials course](https://rockthejvm.com/p/kotlin-essentials) on Rock the JVM. + ## 10. Appendix A As promised, here is the `pom.xml` file that we used to run the code in this article: diff --git a/_posts/2023-05-03-functional-error-handling-in-kotlin.md b/_posts/2023-05-03-functional-error-handling-in-kotlin.md index 917978bbc636..c89221f77732 100644 --- a/_posts/2023-05-03-functional-error-handling-in-kotlin.md +++ b/_posts/2023-05-03-functional-error-handling-in-kotlin.md @@ -17,6 +17,8 @@ If you'd like to watch the video form of this article, please enjoy: The Kotlin language is a multi-paradigm, general-purpose programming language. Whether we develop using an object-oriented or functional approach, we always have the problem of handling errors. Kotlin offers a lot of different methods to handle errors. Still, this article will focus on the functional approaches and introduce the Arrow library. This article is the first part of a series. We'll focus on strategies that deal with the error without managing its cause, i.e., nullable types and Arrow Option types. So, without further ado, let's get started. +> This article assumes you're comfortable with Kotlin. If you need to get those essential skills **as fast as possible** and with thousands of lines of code and a project under your belt, you'll love [Kotlin Essentials](https://rockthejvm.com/p/kotlin-essentials). It's a jam-packed course on **everything** you'll ever need to work with Kotlin for any platform (Android, native, backend, anything), including less-known techniques and language tricks that will make your dev life easier. Check it out [here](https://rockthejvm.com/p/kotlin-essentials). + ## 1. Setup Let's first create the setup we'll use throughout the article as usual. We'll use the last version of Kotlin available at the moment of writing, version 1.8.20. @@ -744,7 +746,11 @@ The salary gap between JobId(value=42) and the max salary is 0.0 ## 5. Conclusions -This article introduced the meaning of functional error handling in Kotlin. We started showing why we shouldn't rely on exceptions to handle errors. Then, we introduced two strategies to handling errors that forget the cause of errors: Kotlin nullable types and the Arrow `Option` type. Moreover, we saw how the Arrow library provides useful DSL to work with both nullable types and the `Option` type. In the next part of this series, we will see different strategies that allow us to propagate the cause of errors, such as the Kotlin `Result` type and the Arrow `Either` type. +This article introduced the meaning of functional error handling in Kotlin. We started showing why we shouldn't rely on exceptions to handle errors. Then, we introduced two strategies to handling errors that forget the cause of errors: Kotlin nullable types and the Arrow `Option` type. Moreover, we saw how the Arrow library provides useful DSL to work with both nullable types and the `Option` type. + +In the next part of this series, we will see different strategies that allow us to propagate the cause of errors, such as the Kotlin `Result` type and the Arrow `Either` type. + +If you found this article too difficult, you can quickly get the experience you need by following the complete [Kotlin Essentials course](https://rockthejvm.com/p/kotlin-essentials) on Rock the JVM. ## 6. Appendix: Maven Configuration diff --git a/_posts/2023-06-16-functional-error-handling-in-kotlin-part-2.md b/_posts/2023-06-16-functional-error-handling-in-kotlin-part-2.md index 353fe8a25546..eab4534a1dcf 100644 --- a/_posts/2023-06-16-functional-error-handling-in-kotlin-part-2.md +++ b/_posts/2023-06-16-functional-error-handling-in-kotlin-part-2.md @@ -15,12 +15,14 @@ In this series [first part](https://blog.rockthejvm.com/functional-error-handlin For the project's setup, please refer to the first part of this series, in which we set up Maven and the needed dependencies. -Without further ado, let's get started! - For the video version, watch below: {% include video id="C0B44WBJJmY" provider="youtube" %} +Without further ado, let's get started! + +> This article, as the first part, requires existing Kotlin experience. If you need to get it **fast** and with thousands of lines of code and a project under your belt, you'll love [Kotlin Essentials](https://rockthejvm.com/p/kotlin-essentials). It's a jam-packed course on **everything** you'll ever need to work with Kotlin for any platform (Android, native, backend, anything), including less-known techniques and language tricks that will make your dev life easier. Check it out [here](https://rockthejvm.com/p/kotlin-essentials). + ## 1. The Domain We'll use extensively the domain model we introduced in the last article. We want to create an application that manages a job board. The main types of the domain are: @@ -928,4 +930,6 @@ And that's all, folks! ## 6. Conclusions -In this second part of the series dedicated to error handling in Kotlin, we introduced the `Result` and the `Either`type. These types represent both the happy and error paths, unlike the types we saw in the first part of the series. We explored their APIs in deep and saw which features the Arrow library offers us to simplify the composition of `Result` and `Either` instances. It's time to recap what we've learned so far. We can use nullable types and the `Option` type if we are not interested in the possible error path of a computation. In Kotlin, such types are quite similar. If we want to know the cause of an error, we can use the `Result` type. Here, we use the subclasses of the `Throwable` type to express the cause. Finally, we use the `Either` type to avoid the `Throwable` type and handle errors using a hierarchy of custom-typed errors. In the last part of this series, we will introduce the upcoming features of the next version of the Arrow library, 1.2.0, which will further simplify the functional handling of errors. \ No newline at end of file +In this second part of the series dedicated to error handling in Kotlin, we introduced the `Result` and the `Either`type. These types represent both the happy and error paths, unlike the types we saw in the first part of the series. We explored their APIs in deep and saw which features the Arrow library offers us to simplify the composition of `Result` and `Either` instances. It's time to recap what we've learned so far. We can use nullable types and the `Option` type if we are not interested in the possible error path of a computation. In Kotlin, such types are quite similar. If we want to know the cause of an error, we can use the `Result` type. Here, we use the subclasses of the `Throwable` type to express the cause. Finally, we use the `Either` type to avoid the `Throwable` type and handle errors using a hierarchy of custom-typed errors. In the last part of this series, we will introduce the upcoming features of the next version of the Arrow library, 1.2.0, which will further simplify the functional handling of errors. + +If you found this article (or the first part) too difficult, you can quickly get the experience you need by following the complete [Kotlin Essentials course](https://rockthejvm.com/p/kotlin-essentials) on Rock the JVM. \ No newline at end of file diff --git a/_posts/2023-07-10-kotlin-context-receivers.md b/_posts/2023-07-10-kotlin-context-receivers.md index a75141e09824..5e212a2346a7 100644 --- a/_posts/2023-07-10-kotlin-context-receivers.md +++ b/_posts/2023-07-10-kotlin-context-receivers.md @@ -17,6 +17,8 @@ In Kotlin, context receivers provide a convenient way to access functions and pr We'll dive deeply into context receivers, starting with their purpose and benefits. We'll explore practical examples and demonstrate how context receivers can make your Kotlin code more expressive and effective. So let's get started and unlock the full potential of context receivers in Kotlin! +> Context Receivers are an experimental feature and requires good knowledge of Kotlin. If you need to get those skills **quickly** and with thousands of lines of code and a project under your belt, we think you'll love [Kotlin Essentials](https://rockthejvm.com/p/kotlin-essentials). It's a jam-packed course on **everything** you'll ever need to work with Kotlin for any platform (Android, native, backend, anything), including less-known techniques and language tricks that will make your dev life easier. Check it out [here](https://rockthejvm.com/p/kotlin-essentials). + If you'd like to watch the video version, please find it below: {% include video id="TVdFAftHzPE" provider="youtube" %} @@ -475,7 +477,11 @@ The final use case for context receivers is to help with typed errors. In fact, ## 5. Conclusion -It's time we sum up what we saw. In this article, we introduced the experimental feature of context receivers in Kotlin. First, we saw the problem it addresses using the use case of type classes, and we first implemented it through extension functions and dispatcher receivers. Then, we saw how context receivers could improve the solution. Finally, we focused on the strengths and weaknesses of context receivers, and we proved that there are better solutions for dependency injection. In the next article, we will see how context receivers can help us handle typed errors functionally and how they'll be used in the next version of the Arrow library. +It's time we sum up what we saw. In this article, we introduced the experimental feature of context receivers in Kotlin. First, we saw the problem it addresses using the use case of type classes, and we first implemented it through extension functions and dispatcher receivers. Then, we saw how context receivers could improve the solution. Finally, we focused on the strengths and weaknesses of context receivers, and we proved that there are better solutions for dependency injection. + +In the next article, we will see how context receivers can help us handle typed errors functionally and how they'll be used in the next version of the Arrow library. + +If you felt that this article was too complex and need to ramp up on Kotlin quickly, do check out the complete [Kotlin Essentials course](https://rockthejvm.com/p/kotlin-essentials). ## 6. Appendix: Gradle Configuration diff --git a/_posts/2023-09-20-functional-error-handling-in-kotlin-part-3.md b/_posts/2023-09-20-functional-error-handling-in-kotlin-part-3.md index 9aacb77af031..7a0848dbaf82 100644 --- a/_posts/2023-09-20-functional-error-handling-in-kotlin-part-3.md +++ b/_posts/2023-09-20-functional-error-handling-in-kotlin-part-3.md @@ -22,6 +22,8 @@ For the video version, watch here: Without further ado, let's start! +> This article requires existing Kotlin experience. If you need to get it **fast** and with thousands of lines of code and a project under your belt, you'll love [Kotlin Essentials](https://rockthejvm.com/p/kotlin-essentials). It's a jam-packed course on **everything** you'll ever need to work with Kotlin for any platform (Android, native, backend, anything), including less-known techniques and language tricks that will make your dev life easier. Check it out [here](https://rockthejvm.com/p/kotlin-essentials). + ## 1. Setup We'll use version 1.9.0 of Kotlin and version 1.2.0 of the Arrow library. In fact, the Raise DSL is not available in previous versions of Arrow. @@ -1292,6 +1294,8 @@ The risen errors are: NonEmptyList(NegativeAmount, InvalidCurrency(message=Curre The long journey throughout the new error-handling style in the Arrow 1.2.0 library has ended. During the path, we introduced the central concept of this article, the `Raise` context, and all its implementing flavors. We saw how to use it to transform and recover a computation in its context. Then, we saw how easy it is to pass from the `Raise` context to any of the available wrapper types, like `Either`, `Option`, and `Result`. We appreciated how smooth is the composition of functions defined in the `Raise` context. Finally, we saw how to use the `Raise` context to accumulate errors. The article should have given you a good overview of the new error handling style in Arrow and how the Arrow guys decided to get rid of a lot of category theory types (did you see any reference to a monoid, monad, applicative, or _traverse_ application?) in favor of a more straight, idiomatic and Kotlinsh approach. +If you found this article (or the ones before it) too difficult, you can quickly get the experience you need by following the Rock the JVM complete [Kotlin Essentials course](https://rockthejvm.com/p/kotlin-essentials). + ## 9. Appendix: Maven Configuration As promised, here is the complete Maven configuration we used in this article: diff --git a/_posts/2024-02-06-kotlin-type-classes.md b/_posts/2024-02-06-kotlin-type-classes.md index c28566a6b5d3..30d2ed3773ee 100644 --- a/_posts/2024-02-06-kotlin-type-classes.md +++ b/_posts/2024-02-06-kotlin-type-classes.md @@ -11,12 +11,14 @@ toc_label: "In this article" _By [Riccardo Cardin](https://github.com/rcardin)_ -In this article, we delve into the concept of type classes in Kotlin, a powerful tool that allows developers to abstract logic for different data types. We'll take data validation as an example to show how type classes can be used to write generic and reusable code. Our implementation will be based on the [Arrow Kt](https://arrow-kt.io/) library, which will exploit Kotlin's context receivers. So, without further ado, let's get the party started. +In this article, we explore the concept of _type classes_ in Kotlin, a powerful tool that allows developers to abstract logic for different data types. We'll take data validation as an example to show how type classes can be used to write generic and reusable code. Our implementation will be based on the [Arrow Kt](https://arrow-kt.io/) library, which will exploit Kotlin's context receivers. So, without further ado, let's get the party started. Video version by Daniel: {% include video id="Qhfiq_1eWM8" provider="youtube" %} +> Type classes are tough. If you need to become proficient in Kotlin **quickly** and with thousands of lines of code and a project under your belt, you'll love [Kotlin Essentials](https://rockthejvm.com/p/kotlin-essentials). It's a jam-packed course on **everything** you'll ever need to work with Kotlin for any platform (Android, native, backend, anything), including less-known techniques and language tricks that will make your dev life easier. Check it out [here](https://rockthejvm.com/p/kotlin-essentials). + ## 1. Setting the Stage We’ll use version 1.9.22 of Kotlin and version 1.2.1 of the Arrow library. We'll also use [Kotlin's context receivers](https://blog.rockthejvm.com/kotlin-context-receivers/). Context receivers are still an experimental feature. Hence, they’re not enabled by default. We need to modify the Gradle configuration. Add the `kotlinOptions` block within the `tasks.withType` block in your `build.gradle.kts` file: @@ -493,6 +495,8 @@ _Et voilà!_ In conclusion, this article has explored the concept of type classes in Kotlin, demonstrating their utility in abstracting validation logic for different data types. We've seen how type classes can solve ad-hoc polymorphism, allowing us to define a set of behaviors that can be applied to various types without altering the types themselves. This approach is advantageous in languages like Kotlin, which supports object-oriented and functional programming paradigms. We've also delved into using Kotlin's context receivers and extension functions to enhance the elegance and intuitiveness of our code. Furthermore, we've seen how the Arrow library can be leveraged to handle validation errors functionally, avoiding exceptions and enhancing code maintainability. However, it's important to note that while type classes offer many advantages, they also come with challenges, such as discoverability and the need for a certain level of familiarity with functional programming concepts. Overall, type classes represent a powerful tool in a developer's toolkit, offering a flexible and maintainable approach to handling everyday programming tasks such as data validation. +Feedback is welcome at daniel@rockthejvm.com! If this article was difficult and you need to ramp up on Kotlin as fast as possible, you'll love the [Kotlin Essentials course](https://rockthejvm.com/p/kotlin-essentials). + ## 7. Appendix: Gradle Configuration As promised, here is the Gradle configuration we used to compile the code in this article. Please set up your project using the `gradle init` command. diff --git a/_posts/2024-04-10-kotlin-flows.md b/_posts/2024-04-10-kotlin-flows.md index 99c0ff5106f7..616c7c6b06b8 100644 --- a/_posts/2024-04-10-kotlin-flows.md +++ b/_posts/2024-04-10-kotlin-flows.md @@ -74,6 +74,8 @@ We have defined the actors playing in the movies "Zack Snyder's Justice League", ## 2. Flows Basics +> If you need to become proficient in Kotlin **quickly** and with thousands of lines of code and a project under your belt, you'll love [Kotlin Essentials](https://rockthejvm.com/p/kotlin-essentials). It's a jam-packed course on **everything** you'll ever need to work with Kotlin for any platform (Android, native, backend, anything), including less-known techniques and language tricks that will make your dev life easier. Check it out [here](https://rockthejvm.com/p/kotlin-essentials). + What is a flow in Kotlin? **A `Flow` is a reactive data structure that emits a sequence of type `T` values**. Flows are part of the Kotlin Coroutines library. In their simplest form, flows can be viewed as a collection, a sequence, or an iterable of values. We can create a flow from a finite list of values using the `flowOf` function: ```kotlin @@ -1312,7 +1314,9 @@ Since the focus of this article is to introduce the main features of flows, we l ## 9. Conclusions -Ladies and gentlemen, we have reached the end of the article. We hope you enjoyed the journey into the world of flows. We saw how to create flows, how to consume them, and how to work with them, both synchronously and concurrently. The article would only be exhaustive in treating some of the features concerning flows. There are a lot of other transformation functions, terminal operations, etc. We invite you to discover and release the full power of flows. In the following appendix, we'll also delve into the internals of flows to understand how they work under the hood. We also left out how to manage hot data sources using flows, but we'll return to the topic in a future post. We hope you found the article helpful and that you learned something new. If you have any questions or feedback, please let us know. We're always happy to hear from you. +Ladies and gentlemen, we have reached the end of the article. We hope you enjoyed the journey into the world of flows. We saw how to create flows, how to consume them, and how to work with them, both synchronously and concurrently. The article would only be exhaustive in treating some of the features concerning flows. There are a lot of other transformation functions, terminal operations, etc. We invite you to discover and release the full power of flows. In the following appendix, we'll also delve into the internals of flows to understand how they work under the hood. We also left out how to manage hot data sources using flows, but we'll return to the topic in a future post. We hope you found the article helpful and that you learned something new. + +If you have any questions or feedback, please let us know. We're always happy to hear from you. If this article was in any way too difficult and you need to become good at Kotlin as fast as possible, we think you'll love the [Kotlin Essentials course](https://rockthejvm.com/p/kotlin-essentials). ## 10. Appendix: How Flows Work