Say goodbye to implicits
Magda Stożek
Contextual abstractions in Scala 3
implicits よさらば
Scala 3 のコンテキスト抽象
Agenda
- About implicits
- Problems in Scala 2
- Use cases - Scala 2 vs Scala 3
implicit の概要、Scala 2 での問題点
Scala 2 と Scala 3 での実践での相違点
Implicits make us powerful
- providing context
- adding functionality
- type classes
- implicit conversions
- dependency injection
- expressing capabilities
- computing new types
- proving relationships between types
implicits は私達を強化する。
コンテキストの提供、機能の追加、型クラス、暗黙の変換など。
Implicits make us miserable
- implicit parameter
- implicit argument
- implicit value
- implicit object
- implicit def
- implicit class
- implicit import incantations
- sneaky conversions
implicits は私達をみじめにする。
おまじない的 import 文。こそこそした変換。
Scala 3
Scala 2
- Providing context
- Adding functionality
- Type classes
- Conversions
vs
Scala 3
コンテキストの提供、機能の追加、型クラスなどについて
Scala 2 と Scala 3 の比較
1. Providing context
- implicit vals
implicit val ec: ExecutionContext = ExecutionContext.global
Future {
def apply[T](body: => T)(implicit executor: ExecutionContext): Future[T] = {...}
}
Scala 2
val myFuture: Future[Int] = Future {
println("Finding the answer...")
42
}
?
?
コンテキストの提供
Scala 2 は implicit val を使う
1. Providing context
- using/given
val myFuture: Future[Int] = Future {
println("Finding the answer...")
42
}
Scala 3
given ec: ExecutionContext = ExecutionContext.global
Future {
def apply[T](body: => T)(using executor: ExecutionContext): Future[T] = {...}
}
?
?
コンテキストの提供
Scala 3 は using と given を使う
2. Adding functionality
object other_package {
case class Book(title: String, pages: Int)
}
val book = Book("Winnie-the-Pooh", 160)
myBook.qualifiesForChallenge //true
val book = Book("Too short", 5)
myBook.qualifiesForChallenge //false
implicit class Qualifier(b: Book) {
def qualifiesForChallenge: Boolean = b.pages > 20
}
?
- implicit classes
Scala 2
機能の追加
Scala 2 は implicit クラスを使う
2. Adding functionality
- extension methods
object other_package {
case class Book(title: String, pages: Int)
}
val book = Book("Winnie-the-Pooh", 160)
myBook.qualifiesForChallenge //true
val book = Book("Too short", 5)
myBook.qualifiesForChallenge //false
?
extension (b: Book)
def qualifiesForChallenge = b.pages > 20
Scala 3
機能の追加
Scala は拡張メソッドを使う
3. Type classes
trait Scorable[T] {
def score(t: T): Int
}
val book = Book("Dune", 600)
val initialScore = CurrentScore(0).addItem(book) // CurrentScore(600)
val article = Article("Understanding type classes")
val newScore = initialScore.addItem(article) // CurrentScore(601)
- implicit val/object/def (with implicit parameters)
implicit val scorableBook = new Scorable[Book] {
override def score(b: Book): Int = b.pages
}
implicit val scorableArticle = new Scorable[Article] {
override def score(t: Article): Int = 1
}
case class CurrentScore(value: Int) {
def addItem[T](item: T)(implicit scoring: Scorable[T]): CurrentScore =
CurrentScore(value + scoring.score(item))
}
Scala 2
型クラス: 暗黙のパラメータの場合
Scala 2 は implicit val/object/def など
?
3. Type classes
- given instances (with using)
given Scorable[Book] with {
override def score(b: Book): Int = b.pages
}
given Scorable[Article] with {
override def score(t: Article): Int = 1
}
case class CurrentScore(value: Int) {
def addItem[T](item: T)(using scoring: Scorable[T]): CurrentScore =
CurrentScore(value + scoring.score(item))
}
trait Scorable[T] {
def score(t: T): Int
}
val book = Book("Dune", 600)
val initialScore = CurrentScore(0).addItem(book) // CurrentScore(600)
val article = Article("Understanding type classes")
val newScore = initialScore.addItem(article) // CurrentScore(601)
Scala 3
型クラス: using の場合
Scala 3 は given インスタンス
?
4. Conversions
- implicit def
case class Item(value: String) extends AnyVal
def print(item: Item): Unit = println(s"*** ${item.value} ***")
val book = Book("Dune", 600)
print(book)
?
implicit def bookToItem(book: Book): Item = Item(book.title)
Scala 2
暗黙の変換
Scala 2 は implicit def
4. Conversions
- Conversion class
case class Item(value: String) extends AnyVal
def print(item: Item): Unit = println(s"*** ${item.value} ***")
val book = Book("Dune", 600)
print(book)
?
given Conversion[Book, Item] with
def apply(book: Book): Item = Item(book.title)
Scala 3
暗黙の変換
Scala 3 は Conversion 型クラス
Summary
- intention, not mechanism
- given/using
- extension methods
- Conversion class
機序ではなく意図を表した構文
Thank you
given Finished[Presentation] with {
override def ask(q: Question): Unit = q.ask()
}
ご清聴ありがとうございました
Say goodbye to implicits [20 min]
By Magda Stożek
Say goodbye to implicits [20 min]
- 689