Upgrade to Pro — share decks privately, control downloads, hide ads and more …

歴史から学ぶ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
  2. 原始時代:ジェネリクスの誕⽣ 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.
  3. 原始時代:ジェネリクスの誕⽣ 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!!
  4. 近世: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)
  5. 近世:Scalaにおける「ジェネリクス」 n 型消去に関しては消去することを「選びとって」いる scala> def isIntIntMap(x: Any) = x match {

    | case m: Map[Int, Int] => true | case _ => false | } <console>: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章
  6. ちなみに:オダスキー先⽣の考え n ”I like type erasure!“ @ Scala Days 2012 cf.

    https://skillsmatter.com/skillscasts/3297-scala-days-closing-remarks
  7. 近代: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
  8. 現代: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