$30 off During Our Annual Pro Sale. View Details »

歴史から学ぶScalaの型消去

biblichor
March 17, 2017

 歴史から学ぶScalaの型消去

biblichor

March 17, 2017
Tweet

Other Decks in Technology

Transcript

  1. 歴史から学ぶ
    Scalaの型消去
    @ 市 ヶ ⾕ G e e k ★ N i g h t # 1 2 S c a l a M a t s u r i の 余 韻 ト ー ク
    〜 祭 り の 余 熱 〜
    @yoshinorikadota
    biblichor

    View Slide

  2. 背景
    Scalaの
    型消去
    ⾟い…?

    View Slide

  3. n 原始
    n 近世
    n 近代
    n 現代
    ジェネリクスの歴史

    View Slide

  4. 原始時代:ジェネリクスの誕⽣
    n 1998年、オダスキー先⽣らによりGeneric Java Language
    Extension誕⽣
    n 2003年、J2SE5.0よりJavaにジェネリクスが導⼊
    n JVMへのコンパイル時、バイトコードに型情報を残さないことで
    1.4以前との「バイナリ互換性」を担保することを選択
    cf. Java Generics and Collections, Chapter 5
    Java implements generics via erasure, which
    ensures that legacy and generic versions usually
    generate identical class files, save for some
    auxiliary information about types. It is possible to
    replace a legacy class file by a generic class file
    without changing, or even recompiling, any client
    code; this is called binary compatibility.

    View Slide

  5. 原始時代:ジェネリクスの誕⽣
    n 1998年、オダスキー先⽣らによりGeneric Java Language
    Extension誕⽣
    n 2003年、J2SE5.0よりJavaにジェネリクスが導⼊
    n JVMへのコンパイル時、バイトコードに型情報を残さないことで
    1.4以前との「バイナリ互換性」を担保することを選択
    cf. Java Generics and Collections, Chapter 5
    Java implements generics via erasure, which
    ensures that legacy and generic versions usually
    generate identical class files, save for some
    auxiliary information about types. It is possible to
    replace a legacy class file by a generic class file
    without changing, or even recompiling, any client
    code; this is called binary compatibility.
    Write once, run anywhere!!

    View Slide

  6. 原始時代:Javaにおける型消去
    n 当時の仕様は「GJ Specification」として今も公開
    (どこかで⾒たことあるような…)
    cf. GJ Specification http://homepages.inf.ed.ac.uk/wadler/gj/Documents/

    View Slide

  7. 近世:Scalaにおける「ジェネリクス」
    n 2003年、Scalaがリリース。Javaのジェネリクスの限界を、
    Scalaでは克服
    n 例:Javaのジェネリクスでは型パラメータは共変/反変ではない
    cf. じゅんいち☆かとうの技術日誌 http://d.hatena.ne.jp/j5ik2o/20101106/1289028031
    public interface Animal {
    }
    public class Dog implements Animal{
    }
    public class App {
    public static void main(String[] args) {
    ArrayList animals = new ArrayList(); // Error!
    ArrayList extends Animal> animals = new ArrayList();
    }
    }

    View Slide

  8. 近世:Scalaにおける「ジェネリクス」
    n ScalaのParametered typeは共変/反変
    cf. じゅんいち☆かとうの技術日誌 http://d.hatena.ne.jp/j5ik2o/20101106/1289028031
    scala> trait Animal
    defined trait Animal
    scala> class Dog extends Animal
    defined class Dog
    scala> val dogs = List(new Dog)
    dogs: List[Dog] = List(Dog@51da6868)
    scala> val animals:List[Animal] = dogs
    animals: List[Animal] = List(Dog@51da6868)

    View Slide

  9. 近世:Scalaにおける「ジェネリクス」
    n 型消去に関しては消去することを「選びとって」いる
    scala> def isIntIntMap(x: Any) = x match {
    | case m: Map[Int, Int] => true
    | case _ => false
    | }
    :15: warning: non-variable type argument Int in type pattern
    scala.collection.immutable.Map[Int,Int] (the underlying of Map[Int,Int]) is unchecked
    case m: Map[Int, Int] => true
    ^
    isIntIntMap: (x: Any)Boolean
    scala> isIntIntMap(Map(1 -> 1))
    res1: Boolean = true
    scala> isIntIntMap(Map("abc" -> "abc"))
    res2: Boolean = true
    cf. 「Scalaスケーラブルプログラミング」第15章

    View Slide

  10. ちなみに:オダスキー先⽣の考え
    n ”I like type erasure!“ @ Scala Days 2012
    cf. https://skillsmatter.com/skillscasts/3297-scala-days-closing-remarks

    View Slide

  11. 近代:Manifestの登場
    n 2008年、Scala 2.7より、Manifestが登場
    def foo[T](x: List[T])(implicit m: Manifest[T]) = {
    if (m <:< manifest[String])
    println("Hey, this list is full of strings")
    else
    println("Non-stringy list")
    }
    foo(List("one", "two")) // Hey, this list is full of strings
    foo(List(1, 2)) // Non-stringy list
    foo(List("one", 2)) // Non-stringy list
    cf. http://stackoverflow.com/questions/3213510/what-is-a-manifest-in-scala-and-when-do-you-need-it

    View Slide

  12. 現代:ClassTag/TypeTag/WeakTypeTagの登場
    n 2013年、Scala 2.10リリース。
    ClassTag/TypeTag/WeakTypeTagが登場
    def foo[A : TypeTag](xs: List[A]) = {
    typeOf[A] match {
    case t if t =:= typeOf[String]
    => println("Hey, this list is full of strings")
    case _
    => println("Non-stringy list")
    }
    }
    foo(List("one", "two")) // Hey, this list is full of strings
    foo(List(1, 2)) // Non-stringy list
    foo(List("one", 2)) // Non-stringy list

    View Slide

  13. 現代:ClassTag/TypeTag/WeakTypeTagの登場
    cf. https://skillsmatter.com/skillscasts/3297-scala-days-closing-remarks

    View Slide

  14. ちなみに:Scalaの「型消去」に関するSpecification
    n 2017年現在、Scala2.11におけるSpecification

    View Slide

  15. まとめ
    n 前提として、デメリットのない選択は存在しな
    い(デメリットがなければ選択ですらない)
    n 「型消去」という仕様は、ScalaがJVM資産の
    活⽤やその実⾏パフォーマンスといった⼤きな
    メリットを得るため、⼩さなデメリットを戦略
    的に選び取った所産
    n また、デメリットを最⼩限にするための⼿当も
    ⽤意している
    n Scalaの特性を活かした開発をするために、こ
    のような⽂脈を理解しておこう(=「歴史から
    学ぶ」)

    View Slide