Share
Embed
Transcript
15 slides
-
歴史から学ぶ 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 -
原始時代:ジェネリクスの誕⽣ 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. -
原始時代:ジェネリクスの誕⽣ 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!! -
近世: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<Animal> animals = new ArrayList<Dog>(); // Error! ArrayList<? extends Animal> animals = new ArrayList<Dog>(); } } -
近世: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) -
近世: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章 -
ちなみに:オダスキー先⽣の考え n ”I like type erasure!“ @ Scala Days 2012 cf.
https://skillsmatter.com/skillscasts/3297-scala-days-closing-remarks -
近代: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 -
現代: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