A Detailed Comparison Between Scala 2 and Scala 3
Scala
A Detailed Comparison Between Scala 2 and Scala 3

Scala
Scala 3, also known as Dotty, represents a significant evolution from Scala 2, introducing a variety of new features and improvements aimed at simplifying the language and enhancing its capabilities. This article provides an in-depth comparison of the major differences between Scala 2 and Scala 3, illustrated with examples.
1. New Syntax and Features
Optional Braces
Scala 3 allows the use of significant indentation as an alternative to braces, aiming to make the code more readable and Python-like.
Scala 2:
object HelloWorld {
def main(args: Array[String]): Unit = {
println("Hello, world!")
}
}
Scala 3:
object HelloWorld:
def main(args: Array[String]): Unit =
println("Hello, world!")
Enums
Scala 3 introduces a new enum construct, replacing the need for sealed trait hierarchies to represent enumerations.
Scala 2:
sealed trait Color
case object Red extends Color
case object Green extends Color
case object Blue extends Color
Scala 3:
enum Color:
case Red, Green, Blue
2. Improvements in Type System
Union and Intersection Types
Scala 3 introduces union and intersection types, providing more flexibility and power in type definitions.
Union Types (Scala 3):
def handle(input: Int | String): Unit =
input match
case i: Int => println(s"Integer: $i")
case s: String => println(s"String: $s")
handle(42) // Integer: 42
handle("hello") // String: hello
Intersection Types (Scala 3):
trait A:
def foo: String = "A"
trait B:
def bar: String = "B"
def combine(x: A & B): String =
x.foo + x.bar
val obj = new A with B
println(combine(obj)) // AB
3. Improvements in Metaprogramming
Inline
Scala 3 introduces the inline keyword, allowing the compiler to inline methods and values, providing better performance and code optimization.
Scala 3 (Using inline):
inline def square(x: Int): Int = x * x
Macros
Scala 3 redefines macros, providing a more robust and integrated metaprogramming capability.
Scala 2:
import scala.language.experimental.macros
import scala.reflect.macros.blackbox.Context
def helloMacro: String = macro helloMacroImpl
def helloMacroImpl(c: Context): c.Expr[String] = {
import c.universe._
c.Expr[String](q""" "Hello, world!" """)
}
Scala 3:
import scala.quoted.*
inline def helloMacro: String = ${ helloMacroImpl }
def helloMacroImpl(using Quotes): Expr[String] = Expr("Hello, world!")
4. Pattern Matching Enhancements
Match Types
Scala 3 introduces match types, allowing types to be matched and transformed in a type-safe manner.
Scala 3:
type Elem[X] = X match
case String => Char
case Array[t] => t
case Iterable[t] => t
val strElem: Elem[String] = 'c'
val arrElem: Elem[Array[Int]] = 42
val listElem: Elem[List[Double]] = 3.14
5. Improvements in Functional Programming
Contextual Abstractions
Scala 3 refines implicits by introducing given, using, and extension methods to make the intent clearer and the code more readable.
Scala 2:
implicit val str: String = "Hello"
def greet(implicit name: String): Unit = println(name)
greet
Scala 3:
given str: String = "Hello"
def greet(using name: String): Unit = println(name)
greet
Type Classes and Extension Methods
Scala 3 provides a more straightforward way to define type classes and extension methods.
Scala 2:
trait Show[T] {
def show(t: T): String
}
object Show {
implicit val intShow: Show[Int] = new Show[Int] {
def show(t: Int): String = t.toString
}
}
def display[T](t: T)(implicit s: Show[T]): String = s.show(t)
display(123)
Scala 3:
trait Show[T]:
def show(t: T): String
given Show[Int] with
def show(t: Int): String = t.toString
def display[T](t: T)(using s: Show[T]): String = s.show(t)
display(123)
6. Syntax and Language Improvements
Type Inference
Scala 3 improves type inference, reducing the need for explicit type annotations in many cases.
Scala 2:
val numbers: List[Int] = List(1, 2, 3)
Scala 3:
val numbers = List(1, 2, 3)
Simplified and Safer Initialization
Scala 3 provides a safer and more straightforward approach to class initialization, reducing common pitfalls associated with uninitialized fields.
Scala 2:
class User(name: String) {
val greet = s"Hello, $name"
}
val user = new User("Scala")
// Field `greet` is initialized with "Hello, Scala"
Scala 3:
class User(val name: String) {
val greet = s"Hello, $name"
}
val user = new User("Scala")
// Field `greet` is initialized with "Hello, Scala"
7. Tooling and Ecosystem Improvements
Scala 3 Compiler (Dotty)
The new compiler for Scala 3, known as Dotty, offers faster compilation times, improved error messages, and better support for new language features.
Migration Tools
Scala 3 provides a suite of tools to assist in migrating code from Scala 2 to Scala 3, including automatic rewriting of certain code patterns and detailed migration guides.
Conclusion
Scala 3 represents a significant step forward from Scala 2, bringing a host of new features and improvements aimed at enhancing the language’s expressiveness, safety, and performance. With new syntax options, refined type system capabilities, enhanced metaprogramming, and improved functional programming support, Scala 3 simplifies many aspects of Scala while introducing powerful new abstractions.
Migrating to Scala 3 may require some effort, but the benefits in terms of code readability, maintainability, and performance are substantial. As the ecosystem continues to evolve, Scala 3 is poised to become the preferred choice for developers looking to leverage the power of the Scala language.
메타데이터
- post_id
- 3ba8c7274e9d
- slug
- a-detailed-comparison-between-scala-2-and-scala-3-3ba8c7274e9d
- url
- https://medium.com/@jorgegfx/a-detailed-comparison-between-scala-2-and-scala-3-3ba8c7274e9d
- canonical_url
- https://medium.com/@jorgegfx/a-detailed-comparison-between-scala-2-and-scala-3-3ba8c7274e9d
- author_url
- https://medium.com/@jorgegfx
- status
- ok
- fetched_at
- 2026-06-27 23:56:40