From bec506f62b9f2e19dda801106bc93f81082aed7f Mon Sep 17 00:00:00 2001 From: Zelenya Date: Fri, 8 Dec 2023 09:57:46 -0800 Subject: [PATCH 1/6] Add an article about migration to Scala 3 --- .../_posts/2023-12-08-migration-to-scala-3.md | 146 ++++++++++++++++++ 1 file changed, 146 insertions(+) create mode 100644 blog/_posts/2023-12-08-migration-to-scala-3.md diff --git a/blog/_posts/2023-12-08-migration-to-scala-3.md b/blog/_posts/2023-12-08-migration-to-scala-3.md new file mode 100644 index 000000000..49b8fbc4a --- /dev/null +++ b/blog/_posts/2023-12-08-migration-to-scala-3.md @@ -0,0 +1,146 @@ +--- +layout: blog-detail +post-type: blog +by: Zelenya +title: "Scala 3: My migration journey" +description: I want to share my journey from Scala 2 to Scala 3 and discuss migration to Scala 3 +--- + +## Implicit context + +Before doing any actual personal work, based on the internet discussions, I had an impression that switching to Scala 3 would be quite painful — in practice, it was pretty straightforward. + +In the retrospect, this was the case because I (and my team) fall into the following buckets: + +- Don’t use IntelliJ; +- Don’t use macros; +- Use Typelevel stack. + +It wouldn’t be as smooth if any of these were different. + +Let’s start in my world first, follow the primary migration steps, and then talk about what to do if your setup and stack differ. + +## Step 0. What does “migration” mean in your case? + +Before you can jump into the action, you (and your team) have to answer a couple of questions. + +If you are actively writing Scala, I’d expect that you don’t choose to stay on Scala 2. Why would anyone want to miss out on all the new features and improvements? Who wouldn’t want to rewrite everything to Scala 3? The reality is not so simple. Some people have monoliths, some use Spark ([which you can already run with Scala 3](https://xebia.com/blog/using-scala-3-with-spark/)), some have no time, and so on. + +There is no one way to do the migration. Decide what’s possible and worthwhile to you (and your company). + +Should you rewrite one service at a time? In what order? Or should you leave the old services untouched and write all the new services in Scala 3? What about internal libraries? How much time and resources can you allocate? (The last one might be the hardest to address) + +It’s also an excellent time to discuss the benefits and trade-offs. And keep it fair. For example, if you just want a new syntax, is it worth disturbing an old service that hasn’t been touched in years? Well, it’s up to you to decide. + +*We decided to write all the new services in Scala 3 (where most of the future work will happen) and keep the rest. Consequently, onboarding new devs without prior Scala experience is one of my biggest challenges.* W*hen they switch from Scala 3 service to Scala 2, they bump into hurdles — some of the “intuitive” concepts don’t work as expected anymore. This requires more explanation; they seem to have to learn some things twice.* + +Okay, we defined what migration means, but how exactly do we go about it? + +## Step 1. Analyze and plan + +Even if we decide not to touch the existing services, we need to review our codebase: + +- Do we have any shared internal libraries? Would we need to use them in new services? +- What external libraries do we use? Do they have a Scala3-compatible release? + +Other questions you might need to consider: + +- How many services do you need to migrate? +- What Scala version(s) does each service use? + +Thanks to the [interoperability](https://docs.scala-lang.org/scala3/guides/migration/compatibility-source.html) between Scala 3 and Scala 2.13, it might be more accessible or crucial to upgrade to Scala 2.13 first. You have to keep this in mind. + +*By this point, we knew that all our services were on 2.13; we knew how many internal libraries needed to be used from both Scala versions and what external libraries had no Scala 3 support: what is the status, what is missing, and what can we do to deal with it. For example, a couple of libraries got a Scala 3 release by the time we were done with the investigation, and one `circe` ”extras” library was replaced with two lines of boilerplate.* + +## Step 2. Draw the rest of the owl + +After all the meetings and/or writings comes the time to do the actual work. When you have concrete questions or action items, remember that [Scala 3 migration guides](https://docs.scala-lang.org/scala3/guides/migration/compatibility-intro.html) are your friends. For example, it covers how to port compiler options and sbt projects. Great reference resource. + +We don’t have to go into these details right now. Instead, let’s talk about the bigger picture and a few other things to remember. + +### Dealing with internal libraries + +There are multiple ways of sharing a library between Scala 2 and Scala 3 services. + +**The good news** is that you can use Scala 2.13 libraries from Scala 3 app and Scala 3 libraries from Scala 2.13 app. + +**The bad news** is that you can’t do it directly if you have shared transitive dependencies. + +**The good news** is that it’s pretty easy to deal with. + +Imagine you have an internal library (e.g., auth-handling, specific DB-connector, peculiar API) used by your existing Scala 2 services that will also be used by Scala 3 services. If your library on Scala 2 uses the `ducks` library and your Scala 3 application uses `ducks` as well, you get two conflicting versions `ducks_2.13` and `ducks_3`. + +To solve this, you can cross-publish your library to both versions by adding one line to your build: + +```scala ++ crossScalaVersions := List("2.13.12", "3.3.1") +``` + +To build against all versions listed in `crossScalaVersions`, prefix the action to run with `+`. For example: + +``` +sbt> + compile +``` + +*At least, that’s what we did — everything else just worked. Your mileage may vary.* + +> For more information, see the guides on [ClassPath compatibility](https://docs.scala-lang.org/scala3/guides/migration/compatibility-classpath.html) and [Cross-building (sbt)](https://www.scala-sbt.org/1.x/docs/Cross-Build.html) or [Cross Builds (mill)](https://mill-build.com/mill/0.9.12/Cross_Builds.html) + +### Dealing with dependencies + +If all the libraries you use are actively maintained and published for Scala 3, good, there is nothing for you to worry about. + +Otherwise, you might need [to help them](https://docs.scala-lang.org/contribute/) with migration or eliminate the dependency. Some libraries can be redundant on Scala 3 (because, for instance, Scala 3 has support for [Type Class Derivation](https://docs.scala-lang.org/scala3/reference/contextual/derivation.html)), and some have new alternatives. + +*For example, at this stage, we’ve discovered [Iron](https://github.com/Iltotore/iron), [a great lightweight library](https://www.youtube.com/watch?v=4pq1elOap9k&ab_channel=ImpurePics) for type constraints, which replaced refined and newtype libraries in one go.* + +### Dealing with plugins + +Similar to dependencies, some plugins stay working, and some — are redundant and can be dropped. +For instance, the first plugin I was happy to retire was `better-monadic-for`, because Scala 3 already gives me better for-comprehensions: + +```scala +for + // Can't do this in vanilla Scala 2: + given Logger[IO] <- makeLoggerOrSomething + result <- doX +yield doY(result) +``` + +The second one is `kind-projector`. Scala 3 has [built-in type lambda syntax](https://docs.scala-lang.org/scala3/reference/new-types/type-lambdas-spec.html) and [kind-projector compatible syntax](https://docs.scala-lang.org/scala3/reference/changed-features/wildcards.html). + +> For even more information, see the [Kind Projector Migration](https://docs.scala-lang.org/scala3/guides/migration/plugin-kind-projector.html) guide. + +### Finally, dealing with code + +Much of the Scala 2.13 code is still valid in Scala 3. If you want, you can use [the migration tools](https://docs.scala-lang.org/scala3/guides/migration/tooling-tour.html). Otherwise, if it sounds too boring, you can copy-paste the code over and fix whatever’s red. + +> You can review the incompatibilities in the [Incompatibility Table](https://docs.scala-lang.org/scala3/guides/migration/incompatibility-table.html). + +You might be wondering about all the new concepts and changes. For example, what should be done about `implicit` splits or enums? You don’t have to rewrite everything right away. Here and there, you can keep using the `implicit` keyword instead of `given` and `using`. Same with enums — you can keep using ADTs in the form of sealed traits with case classes and refactor to the new enums later. + +However, it’s an exceptional opportunity to think about the style, patterns, and consistency. The code tends to replicate and spread around via copy-paste. You must decide whether to pay upfront or take shortcuts and do a more significant refactoring later. + +Scala-3-rewrite allows you to get rid of the old workarounds as well as challenge and improve on your established Scala 2 patterns. *For instance, I was happy to try [error-handling](https://gvolpe.com/blog/error-handling-scala3/) with [union types](https://docs.scala-lang.org/scala3/book/types-union.html) and use new deriving mechanisms, but I’m still trying to find a more ergonomic usage for enums.* + +## Side quests + +### What to do about IDEs / IntelliJ IDEA + +*I might not be the last person you should ask about IDEs, but I am still quite biased when it comes to tooling. I vividly remember a few years ago when the functional code (with `cats`) was primarily red. Also, I haven’t touched any Java IDEs in years; I mainly work with unpopular functional languages and am happy with syntax (plus error) highlighting and go-to-definitions. And if I don’t need to restart the LSP server a few times a day, I’m in heaven.* + +To me, using VS Code with Metals and Scala 3 doesn’t feel different from using these with Scala 2 a couple of years ago. And it’s only getting better. + +[IntelliJ IDEA 2023.2](https://blog.jetbrains.com/scala/2023/07/26/intellij-scala-plugin-2023-2-is-out/) brought enhanced Scala 3 support, and the team is constantly working on improvements. [Metals](https://scalameta.org/metals/) has regular [releases](https://scalameta.org/metals/blog/) driven by [Scala Center](https://scala.epfl.ch/), [VirtusLab](https://virtuslab.com/), and contributors from the community. So, if you haven’t recently tried either, now is a good time. + +### What to do about macros (and other issues) + +First, as discussed earlier, you should ask whether macros live in a separate unmaintainable service? Can you leave these services alone for now and rewrite them later? Or can you extract the usage of the macros into an independent service or a library? + +And if the macros rewrite is unavoidable but unattainable, consider asking for help. For instance, [VirtusLab](https://virtuslab.com/) offers [free support with migration](https://virtuslab.com/scala-3-support-and-migration/). + +## Next steps + +Hope this clears up and demystifies some things. + +I’d also encourage you to share your migration stories even if they seem boring. Also, remember that the IntelliJ Scala plugin team asks for [feedback](https://blog.jetbrains.com/scala/2023/09/21/intellijscala-scala-days-2023-madrid/), and [Scala Center](https://scala.epfl.ch/) regularly collects feedback. From 6e0128989b0ef4417f1edd24ef49241e5e07106c Mon Sep 17 00:00:00 2001 From: Zelenya Date: Sat, 16 Dec 2023 20:55:33 +0100 Subject: [PATCH 2/6] Apply suggestions from code review Co-authored-by: Anatolii Kmetiuk --- .../_posts/2023-12-08-migration-to-scala-3.md | 37 +++++++++++-------- 1 file changed, 22 insertions(+), 15 deletions(-) diff --git a/blog/_posts/2023-12-08-migration-to-scala-3.md b/blog/_posts/2023-12-08-migration-to-scala-3.md index 49b8fbc4a..a1d9ed6d1 100644 --- a/blog/_posts/2023-12-08-migration-to-scala-3.md +++ b/blog/_posts/2023-12-08-migration-to-scala-3.md @@ -6,17 +6,13 @@ title: "Scala 3: My migration journey" description: I want to share my journey from Scala 2 to Scala 3 and discuss migration to Scala 3 --- -## Implicit context - -Before doing any actual personal work, based on the internet discussions, I had an impression that switching to Scala 3 would be quite painful — in practice, it was pretty straightforward. +I want to share my journey from Scala 2 to Scala 3 and discuss migration to Scala 3. -In the retrospect, this was the case because I (and my team) fall into the following buckets: +## Implicit context -- Don’t use IntelliJ; -- Don’t use macros; -- Use Typelevel stack. +I am just a software engineer. Before doing any actual personal work, based on the internet discussions, I had an impression that switching to Scala 3 would be quite painful — in practice, it was pretty straightforward. -It wouldn’t be as smooth if any of these were different. +In retrospect, our experience was determined by the technology stack and tools that I (and my team) use: microservices, Typelevel stack, VS Code with Metals, and, most importantly, no macros. It might not be as smooth if any of these wasn't the case. Let’s start in my world first, follow the primary migration steps, and then talk about what to do if your setup and stack differ. @@ -32,7 +28,7 @@ Should you rewrite one service at a time? In what order? Or should you leave the It’s also an excellent time to discuss the benefits and trade-offs. And keep it fair. For example, if you just want a new syntax, is it worth disturbing an old service that hasn’t been touched in years? Well, it’s up to you to decide. -*We decided to write all the new services in Scala 3 (where most of the future work will happen) and keep the rest. Consequently, onboarding new devs without prior Scala experience is one of my biggest challenges.* W*hen they switch from Scala 3 service to Scala 2, they bump into hurdles — some of the “intuitive” concepts don’t work as expected anymore. This requires more explanation; they seem to have to learn some things twice.* +*We decided to write all the new services in Scala 3 (where most of the future work will happen) and keep the rest. Consequently, onboarding new devs without prior Scala experience is one of my biggest challenges. When they switch from Scala 3 service to Scala 2, they bump into hurdles — some of the “intuitive” concepts don’t work as expected anymore. This requires more explanation; they seem to have to learn some things twice.* Okay, we defined what migration means, but how exactly do we go about it? @@ -50,11 +46,13 @@ Other questions you might need to consider: Thanks to the [interoperability](https://docs.scala-lang.org/scala3/guides/migration/compatibility-source.html) between Scala 3 and Scala 2.13, it might be more accessible or crucial to upgrade to Scala 2.13 first. You have to keep this in mind. -*By this point, we knew that all our services were on 2.13; we knew how many internal libraries needed to be used from both Scala versions and what external libraries had no Scala 3 support: what is the status, what is missing, and what can we do to deal with it. For example, a couple of libraries got a Scala 3 release by the time we were done with the investigation, and one `circe` ”extras” library was replaced with two lines of boilerplate.* +*By this point, we knew that all our services were on 2.13; we knew how many internal libraries needed to be used from both Scala versions and what external libraries had no Scala 3 support: what the status is, what is missing, and what we can do to deal with it. For example, a couple of libraries got a Scala 3 release by the time we were done with the investigation, and one `circe` ”extras” library was replaced with two lines of boilerplate.* ## Step 2. Draw the rest of the owl -After all the meetings and/or writings comes the time to do the actual work. When you have concrete questions or action items, remember that [Scala 3 migration guides](https://docs.scala-lang.org/scala3/guides/migration/compatibility-intro.html) are your friends. For example, it covers how to port compiler options and sbt projects. Great reference resource. +After all the meetings and/or writings comes the time to do the actual work. When you have concrete questions or action items, remember that [Scala 3 migration guides](https://docs.scala-lang.org/scala3/guides/migration/compatibility-intro.html) are your friends. For example, it covers how to port compiler options and build configurations. Great reference resource. + +> Note that you can find further help from the community on [Scala Discord](https://discord.com/invite/scala). We don’t have to go into these details right now. Instead, let’s talk about the bigger picture and a few other things to remember. @@ -70,7 +68,7 @@ There are multiple ways of sharing a library between Scala 2 and Scala 3 service Imagine you have an internal library (e.g., auth-handling, specific DB-connector, peculiar API) used by your existing Scala 2 services that will also be used by Scala 3 services. If your library on Scala 2 uses the `ducks` library and your Scala 3 application uses `ducks` as well, you get two conflicting versions `ducks_2.13` and `ducks_3`. -To solve this, you can cross-publish your library to both versions by adding one line to your build: +To solve this, with sbt, you can cross-publish your library to both versions by adding one line to your build: ```scala + crossScalaVersions := List("2.13.12", "3.3.1") @@ -97,16 +95,25 @@ Otherwise, you might need [to help them](https://docs.scala-lang.org/contribute/ ### Dealing with plugins Similar to dependencies, some plugins stay working, and some — are redundant and can be dropped. -For instance, the first plugin I was happy to retire was `better-monadic-for`, because Scala 3 already gives me better for-comprehensions: + +For instance, the first plugin I was happy to retire was `better-monadic-for`, because Scala 3 already gives me better for-comprehensions. For example, we can define implicit values inside for-comprehensions: ```scala +// Scala 3 for - // Can't do this in vanilla Scala 2: given Logger[IO] <- makeLoggerOrSomething result <- doX yield doY(result) ``` +```scala +// Scala 2 with better-monadic-for +for + implicit0(logger: Logger[IO]) <- makeLoggerOrSomething + result <- doX +yield doY(result) +``` + The second one is `kind-projector`. Scala 3 has [built-in type lambda syntax](https://docs.scala-lang.org/scala3/reference/new-types/type-lambdas-spec.html) and [kind-projector compatible syntax](https://docs.scala-lang.org/scala3/reference/changed-features/wildcards.html). > For even more information, see the [Kind Projector Migration](https://docs.scala-lang.org/scala3/guides/migration/plugin-kind-projector.html) guide. @@ -131,7 +138,7 @@ Scala-3-rewrite allows you to get rid of the old workarounds as well as challeng To me, using VS Code with Metals and Scala 3 doesn’t feel different from using these with Scala 2 a couple of years ago. And it’s only getting better. -[IntelliJ IDEA 2023.2](https://blog.jetbrains.com/scala/2023/07/26/intellij-scala-plugin-2023-2-is-out/) brought enhanced Scala 3 support, and the team is constantly working on improvements. [Metals](https://scalameta.org/metals/) has regular [releases](https://scalameta.org/metals/blog/) driven by [Scala Center](https://scala.epfl.ch/), [VirtusLab](https://virtuslab.com/), and contributors from the community. So, if you haven’t recently tried either, now is a good time. +[IntelliJ IDEA 2023.2](https://blog.jetbrains.com/scala/2023/07/26/intellij-scala-plugin-2023-2-is-out/) brought enhanced Scala 3 support, and the team is constantly working on improvements ([IntelliJ IDEA 2023.3](https://blog.jetbrains.com/scala/2023/12/07/intellij-scala-plugin-2023-3-is-out/) was released just when I was writing this). [Metals](https://scalameta.org/metals/) has regular [releases](https://scalameta.org/metals/blog/) driven by [Scala Center](https://scala.epfl.ch/), [VirtusLab](https://virtuslab.com/), and contributors from the community. So, if you haven’t recently tried either, now is a good time. ### What to do about macros (and other issues) From 7741e4580b65a9cbba40db508041907df6598f46 Mon Sep 17 00:00:00 2001 From: Zelenya Date: Wed, 20 Dec 2023 08:48:46 -0800 Subject: [PATCH 3/6] Apply suggestions from code review --- blog/_posts/2023-12-08-migration-to-scala-3.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/blog/_posts/2023-12-08-migration-to-scala-3.md b/blog/_posts/2023-12-08-migration-to-scala-3.md index a1d9ed6d1..0b2bbb2bd 100644 --- a/blog/_posts/2023-12-08-migration-to-scala-3.md +++ b/blog/_posts/2023-12-08-migration-to-scala-3.md @@ -6,11 +6,11 @@ title: "Scala 3: My migration journey" description: I want to share my journey from Scala 2 to Scala 3 and discuss migration to Scala 3 --- -I want to share my journey from Scala 2 to Scala 3 and discuss migration to Scala 3. +My name is Jay, I am a software engineer and developer advocate. We've recently migrated the project from Scala 2 to Scala 3 at $WORK, and in this article, I'd like to share the lessons learned and tips. ## Implicit context -I am just a software engineer. Before doing any actual personal work, based on the internet discussions, I had an impression that switching to Scala 3 would be quite painful — in practice, it was pretty straightforward. +Before doing any actual personal work, based on the internet discussions, I had an impression that switching to Scala 3 would be quite painful — in practice, it was pretty straightforward. In retrospect, our experience was determined by the technology stack and tools that I (and my team) use: microservices, Typelevel stack, VS Code with Metals, and, most importantly, no macros. It might not be as smooth if any of these wasn't the case. @@ -50,7 +50,7 @@ Thanks to the [interoperability](https://docs.scala-lang.org/scala3/guides/migr ## Step 2. Draw the rest of the owl -After all the meetings and/or writings comes the time to do the actual work. When you have concrete questions or action items, remember that [Scala 3 migration guides](https://docs.scala-lang.org/scala3/guides/migration/compatibility-intro.html) are your friends. For example, it covers how to port compiler options and build configurations. Great reference resource. +After all the meetings and/or writings comes the time to do the actual work. When you have concrete questions or action items, remember that [Scala 3 migration guides](https://docs.scala-lang.org/scala3/guides/migration/compatibility-intro.html) are your friends. For example, they cover how to port compiler options and build configurations. Great reference resource. > Note that you can find further help from the community on [Scala Discord](https://discord.com/invite/scala). From 1ada5a10a893795adeb0a51ac54fe93d0739d998 Mon Sep 17 00:00:00 2001 From: Zelenya Date: Thu, 21 Dec 2023 21:15:21 +0100 Subject: [PATCH 4/6] Apply suggestions from code review MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Sébastien Doeraene --- .../_posts/2023-12-08-migration-to-scala-3.md | 54 +++++++++---------- 1 file changed, 25 insertions(+), 29 deletions(-) diff --git a/blog/_posts/2023-12-08-migration-to-scala-3.md b/blog/_posts/2023-12-08-migration-to-scala-3.md index 0b2bbb2bd..8d88207f2 100644 --- a/blog/_posts/2023-12-08-migration-to-scala-3.md +++ b/blog/_posts/2023-12-08-migration-to-scala-3.md @@ -6,15 +6,15 @@ title: "Scala 3: My migration journey" description: I want to share my journey from Scala 2 to Scala 3 and discuss migration to Scala 3 --- -My name is Jay, I am a software engineer and developer advocate. We've recently migrated the project from Scala 2 to Scala 3 at $WORK, and in this article, I'd like to share the lessons learned and tips. +My name is Jay, I am a software engineer and developer advocate. We've recently migrated a major project from Scala 2 to Scala 3 at $WORK. In this article, I'd like to share the lessons we learned as well as some tips. ## Implicit context -Before doing any actual personal work, based on the internet discussions, I had an impression that switching to Scala 3 would be quite painful — in practice, it was pretty straightforward. +Before doing any actual personal work, based on Internet discussions, I had the impression that switching to Scala 3 would be quite painful. In practice, it was pretty straightforward. -In retrospect, our experience was determined by the technology stack and tools that I (and my team) use: microservices, Typelevel stack, VS Code with Metals, and, most importantly, no macros. It might not be as smooth if any of these wasn't the case. +In retrospect, our experience was determined by the technology stack and tools that I (and my team) use: a microservice architecture, the Typelevel stack, VS Code with Metals, and, most importantly, no macros. It might not have been as smooth if any of these wasn't the case. -Let’s start in my world first, follow the primary migration steps, and then talk about what to do if your setup and stack differ. +Let’s first explore our experience given that setup, follow the primary migration steps, and then we will talk about what to do if your setup and stack differ. ## Step 0. What does “migration” mean in your case? @@ -24,13 +24,11 @@ If you are actively writing Scala, I’d expect that you don’t choose to stay There is no one way to do the migration. Decide what’s possible and worthwhile to you (and your company). -Should you rewrite one service at a time? In what order? Or should you leave the old services untouched and write all the new services in Scala 3? What about internal libraries? How much time and resources can you allocate? (The last one might be the hardest to address) +Should you rewrite one service at a time? In what order? Or should you leave the old services untouched and write all the new services in Scala 3? What about internal libraries? How much time and resources can you allocate? The latter question might be the hardest. -It’s also an excellent time to discuss the benefits and trade-offs. And keep it fair. For example, if you just want a new syntax, is it worth disturbing an old service that hasn’t been touched in years? Well, it’s up to you to decide. +It’s also an excellent time to discuss the benefits and trade-offs. Keep it fair. For example, if you just want a new syntax, is it worth disturbing an old service that hasn’t been touched in years? Well, it’s up to you to decide. -*We decided to write all the new services in Scala 3 (where most of the future work will happen) and keep the rest. Consequently, onboarding new devs without prior Scala experience is one of my biggest challenges. When they switch from Scala 3 service to Scala 2, they bump into hurdles — some of the “intuitive” concepts don’t work as expected anymore. This requires more explanation; they seem to have to learn some things twice.* - -Okay, we defined what migration means, but how exactly do we go about it? +We decided to write all the new services in Scala 3 (where most of the future work will happen) while keeping the existing ones on Scala 2. Consequently, onboarding new developers without prior Scala experience is one of my biggest challenges. When they switch from a Scala 3 service to Scala 2, they bump into hurdles — some of the “intuitive” concepts don’t work as expected anymore. This requires more explanation; they seem to have to learn some things twice. ## Step 1. Analyze and plan @@ -50,13 +48,11 @@ Thanks to the [interoperability](https://docs.scala-lang.org/scala3/guides/migr ## Step 2. Draw the rest of the owl -After all the meetings and/or writings comes the time to do the actual work. When you have concrete questions or action items, remember that [Scala 3 migration guides](https://docs.scala-lang.org/scala3/guides/migration/compatibility-intro.html) are your friends. For example, they cover how to port compiler options and build configurations. Great reference resource. - -> Note that you can find further help from the community on [Scala Discord](https://discord.com/invite/scala). +After all the meetings and/or write-ups comes the time to do the actual work. When you have concrete questions or action items, remember that [Scala 3 migration guides](https://docs.scala-lang.org/scala3/guides/migration/compatibility-intro.html) are your friends. For example, they cover how to port compiler options and build configurations. They are a great reference resource. -We don’t have to go into these details right now. Instead, let’s talk about the bigger picture and a few other things to remember. +> Note that you can find further help from the community on the [Scala Discord](https://discord.com/invite/scala). -### Dealing with internal libraries +### Internal libraries There are multiple ways of sharing a library between Scala 2 and Scala 3 services. @@ -66,7 +62,7 @@ There are multiple ways of sharing a library between Scala 2 and Scala 3 service **The good news** is that it’s pretty easy to deal with. -Imagine you have an internal library (e.g., auth-handling, specific DB-connector, peculiar API) used by your existing Scala 2 services that will also be used by Scala 3 services. If your library on Scala 2 uses the `ducks` library and your Scala 3 application uses `ducks` as well, you get two conflicting versions `ducks_2.13` and `ducks_3`. +Imagine you have an internal library (e.g., authentication handling, a specific database connector, a peculiar API) used by your existing Scala 2 services that will also be used by Scala 3 services. If your library on Scala 2 uses the `ducks` library and your Scala 3 application uses `ducks` as well, you get two conflicting versions `ducks_2.13` and `ducks_3`. To solve this, with sbt, you can cross-publish your library to both versions by adding one line to your build: @@ -84,19 +80,19 @@ sbt> + compile > For more information, see the guides on [ClassPath compatibility](https://docs.scala-lang.org/scala3/guides/migration/compatibility-classpath.html) and [Cross-building (sbt)](https://www.scala-sbt.org/1.x/docs/Cross-Build.html) or [Cross Builds (mill)](https://mill-build.com/mill/0.9.12/Cross_Builds.html) -### Dealing with dependencies +### Dependencies -If all the libraries you use are actively maintained and published for Scala 3, good, there is nothing for you to worry about. +If all the libraries you use are actively maintained and published for Scala 3, there is nothing for you to worry about. Otherwise, you might need [to help them](https://docs.scala-lang.org/contribute/) with migration or eliminate the dependency. Some libraries can be redundant on Scala 3 (because, for instance, Scala 3 has support for [Type Class Derivation](https://docs.scala-lang.org/scala3/reference/contextual/derivation.html)), and some have new alternatives. *For example, at this stage, we’ve discovered [Iron](https://github.com/Iltotore/iron), [a great lightweight library](https://www.youtube.com/watch?v=4pq1elOap9k&ab_channel=ImpurePics) for type constraints, which replaced refined and newtype libraries in one go.* -### Dealing with plugins +### Plugins -Similar to dependencies, some plugins stay working, and some — are redundant and can be dropped. +Similarly to dependencies, some plugins support Scala 3, while some others are redundant and can be dropped. -For instance, the first plugin I was happy to retire was `better-monadic-for`, because Scala 3 already gives me better for-comprehensions. For example, we can define implicit values inside for-comprehensions: +The first plugin we were happy to retire was `better-monadic-for`, because Scala 3 already gives me better for-comprehensions. For example, we can define implicit values inside for-comprehensions: ```scala // Scala 3 @@ -116,15 +112,15 @@ yield doY(result) The second one is `kind-projector`. Scala 3 has [built-in type lambda syntax](https://docs.scala-lang.org/scala3/reference/new-types/type-lambdas-spec.html) and [kind-projector compatible syntax](https://docs.scala-lang.org/scala3/reference/changed-features/wildcards.html). -> For even more information, see the [Kind Projector Migration](https://docs.scala-lang.org/scala3/guides/migration/plugin-kind-projector.html) guide. +> For even more information, see the [Kind Projector migration guide](https://docs.scala-lang.org/scala3/guides/migration/plugin-kind-projector.html). -### Finally, dealing with code +### Finally, code Much of the Scala 2.13 code is still valid in Scala 3. If you want, you can use [the migration tools](https://docs.scala-lang.org/scala3/guides/migration/tooling-tour.html). Otherwise, if it sounds too boring, you can copy-paste the code over and fix whatever’s red. > You can review the incompatibilities in the [Incompatibility Table](https://docs.scala-lang.org/scala3/guides/migration/incompatibility-table.html). -You might be wondering about all the new concepts and changes. For example, what should be done about `implicit` splits or enums? You don’t have to rewrite everything right away. Here and there, you can keep using the `implicit` keyword instead of `given` and `using`. Same with enums — you can keep using ADTs in the form of sealed traits with case classes and refactor to the new enums later. +You might be wondering about all the new concepts and changes. For example, what should be done about `implicit` splits or enums? You don’t have to rewrite everything right away. Here and there, you can keep using the `implicit` keyword instead of `given` and `using`. The same applies to enums: you can keep using ADTs in the form of sealed traits with case classes and refactor to the new enums later. However, it’s an exceptional opportunity to think about the style, patterns, and consistency. The code tends to replicate and spread around via copy-paste. You must decide whether to pay upfront or take shortcuts and do a more significant refactoring later. @@ -134,20 +130,20 @@ Scala-3-rewrite allows you to get rid of the old workarounds as well as challeng ### What to do about IDEs / IntelliJ IDEA -*I might not be the last person you should ask about IDEs, but I am still quite biased when it comes to tooling. I vividly remember a few years ago when the functional code (with `cats`) was primarily red. Also, I haven’t touched any Java IDEs in years; I mainly work with unpopular functional languages and am happy with syntax (plus error) highlighting and go-to-definitions. And if I don’t need to restart the LSP server a few times a day, I’m in heaven.* +*I might not be the best person you should ask about IDEs, but I am still quite biased when it comes to tooling. I vividly remember a few years ago when the functional code (with `cats`) was primarily red. Also, I haven’t touched any Java IDEs in years; I mainly work with unpopular functional languages and am happy with syntax (plus error) highlighting and go-to-definitions. And if I don’t need to restart the LSP server a few times a day, I’m in heaven.* To me, using VS Code with Metals and Scala 3 doesn’t feel different from using these with Scala 2 a couple of years ago. And it’s only getting better. -[IntelliJ IDEA 2023.2](https://blog.jetbrains.com/scala/2023/07/26/intellij-scala-plugin-2023-2-is-out/) brought enhanced Scala 3 support, and the team is constantly working on improvements ([IntelliJ IDEA 2023.3](https://blog.jetbrains.com/scala/2023/12/07/intellij-scala-plugin-2023-3-is-out/) was released just when I was writing this). [Metals](https://scalameta.org/metals/) has regular [releases](https://scalameta.org/metals/blog/) driven by [Scala Center](https://scala.epfl.ch/), [VirtusLab](https://virtuslab.com/), and contributors from the community. So, if you haven’t recently tried either, now is a good time. +[IntelliJ IDEA 2023.2](https://blog.jetbrains.com/scala/2023/07/26/intellij-scala-plugin-2023-2-is-out/) brought enhanced Scala 3 support, and the team is constantly working on improvements ([IntelliJ IDEA 2023.3](https://blog.jetbrains.com/scala/2023/12/07/intellij-scala-plugin-2023-3-is-out/) was released just when I was writing this). [Metals](https://scalameta.org/metals/) has regular [releases](https://scalameta.org/metals/blog/) driven by the [Scala Center](https://scala.epfl.ch/), [VirtusLab](https://virtuslab.com/), and contributors from the community. So, if you haven’t recently tried either, now is a good time. ### What to do about macros (and other issues) -First, as discussed earlier, you should ask whether macros live in a separate unmaintainable service? Can you leave these services alone for now and rewrite them later? Or can you extract the usage of the macros into an independent service or a library? +First, as discussed earlier, you should ask whether macros live in a separate service? Can you leave these services alone for now and rewrite them later? Or can you extract the usage of the macros into an independent service or a library? -And if the macros rewrite is unavoidable but unattainable, consider asking for help. For instance, [VirtusLab](https://virtuslab.com/) offers [free support with migration](https://virtuslab.com/scala-3-support-and-migration/). +If the macros rewrite is unavoidable but unattainable, consider asking for help. For instance, [VirtusLab](https://virtuslab.com/) offers [free support with migration](https://virtuslab.com/scala-3-support-and-migration/). ## Next steps -Hope this clears up and demystifies some things. +I hope this clears up and demystifies some things. -I’d also encourage you to share your migration stories even if they seem boring. Also, remember that the IntelliJ Scala plugin team asks for [feedback](https://blog.jetbrains.com/scala/2023/09/21/intellijscala-scala-days-2023-madrid/), and [Scala Center](https://scala.epfl.ch/) regularly collects feedback. +I’d also encourage you to share your migration stories even if they seem boring. Also, remember that the IntelliJ Scala plugin team asks for [feedback](https://blog.jetbrains.com/scala/2023/09/21/intellijscala-scala-days-2023-madrid/), and the [Scala Center](https://scala.epfl.ch/) regularly collects feedback. From 66472f5142aa416203234cd42d16fa42f7c1a1ac Mon Sep 17 00:00:00 2001 From: Jamie Thompson Date: Mon, 22 Jan 2024 16:26:12 +0100 Subject: [PATCH 5/6] Rename 2023-12-08-migration-to-scala-3.md to 2024-01-22-migration-to-scala-3.md update date of publish --- ...migration-to-scala-3.md => 2024-01-22-migration-to-scala-3.md} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename blog/_posts/{2023-12-08-migration-to-scala-3.md => 2024-01-22-migration-to-scala-3.md} (100%) diff --git a/blog/_posts/2023-12-08-migration-to-scala-3.md b/blog/_posts/2024-01-22-migration-to-scala-3.md similarity index 100% rename from blog/_posts/2023-12-08-migration-to-scala-3.md rename to blog/_posts/2024-01-22-migration-to-scala-3.md From 07d0c3523b543bab70cd1f855995e52f074840ad Mon Sep 17 00:00:00 2001 From: Anatolii Kmetiuk Date: Mon, 22 Jan 2024 16:48:05 +0100 Subject: [PATCH 6/6] Schedule the Migration blog article for 23.01.24 --- ...migration-to-scala-3.md => 2024-01-23-migration-to-scala-3.md} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename blog/_posts/{2024-01-22-migration-to-scala-3.md => 2024-01-23-migration-to-scala-3.md} (100%) diff --git a/blog/_posts/2024-01-22-migration-to-scala-3.md b/blog/_posts/2024-01-23-migration-to-scala-3.md similarity index 100% rename from blog/_posts/2024-01-22-migration-to-scala-3.md rename to blog/_posts/2024-01-23-migration-to-scala-3.md