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

こんなに違う!ScalaとKotlin

 こんなに違う!ScalaとKotlin

Yuichi Maekawa

June 28, 2019
Tweet

More Decks by Yuichi Maekawa

Other Decks in Programming

Transcript

  1. kaelaela(まえかわ ゆういち) Backend engineer at アルプ株式会社/Alp, Inc Work: Scala with

    DDD with Eff Twitter: _kaelaela GitHub: kaelaela Scala: helf a year Kotlin: 2.5 years
  2. Scala philosophy / Scalaの哲学 Scalable language スケーラブルな言語 Unifies object-oriented and

    functional programming オブジェクト指向と関数型の統合 Interoperates seamlessly with Java Javaとのシームレスな相互運用
  3. Scala and Kotlin are similar data class User( var name:

    String = "anonymous" ) 似てる! case class User( name: String = "anonymous" )
  4. Scala and Kotlin are VERY similar data class User... val

    user = User().apply { name = "yuichi" } println(user.name) // yuichi case class User... val user = User.apply( name = "yuichi" ) println(user.name) // yuichi めっちゃ似てる!
  5. Scala case class User... val user = User.apply( name =

    "yuichi" ) println(user.name) // yuichi Tiny diff…? Kotlin data class User... val user = User().apply { name = "yuichi" } println(user.name) // yuichi チョット違う…?
  6. case class User… object User { def apply(name: String): User

    = new User(name) def main(args: Array[String]) = { val user = User.apply(name = "yuichi") println(user.name) } } How is the class defined? data class User… fun main() { val user = User().apply {name = "yuichi"} println(user.name) } クラスはどう?
  7. case class User… object User { def apply(name: String): User

    = new User(name) def main(args: Array[String]) = { val user = User.apply(name = "yuichi") println(user.name) } } data class User… fun main() { val user = User().apply {name = "yuichi"} println(user.name) } Very different... 全然違う…
  8. case class User… object User { def apply(name: String): User

    = new User(name) def main(args: Array[String]) = { val user = User.apply(name = "yuichi") println(user.name) } } data class User… fun main() { val user = User().apply {name = "yuichi"} println(user.name) } KotlinはObjectがなくていい Top level function(Kotlin)
  9. case class User… object User { def apply(name: String): User

    = new User(name) def main(args: Array[String]) = { val user = User.apply(name = "yuichi") println(user.name) } } data class User… fun main() { val user = User().apply {name = "yuichi"} println(user.name) } Apply function Scope function Kotlinのapplyはスコープ関数 Different function
  10. How is Scala code decompiled? public void main(final String[] args)

    { User user = User$.MODULE$.apply("yuichi"); .MODULE$.println(user.name()); } Scalaをデコンパイルするとシンプル
  11. How is Kotlin code decompiled? public final class UserKt {

    public static final void main() { User var1 = new User((String)null, 1, (DefaultConstructorMarker)null); ~~~ // some variables by scope function var1.setName("yuichi"); String var6 = var1.getName(); ~~~ System.out.println(var6); } public static void main(String[] var0) { main(); } } Kotlinをデコンパイルすると?
  12. Top level function == ~~Kt class public final class UserKt

    { public static final void main() { User var1 = new User((String)null, 1, (DefaultConstructorMarker)null); ~~~ var1.setName("yuichi"); String var6 = var1.getName(); ~~~ System.out.println(var6); } public static void main(String[] var0) { main(); } } 関数をトップにするとXXXKtクラスが自動生成
  13. Kotlin fun main() { val list = listOf(1) when (list)

    { is MutableList -> { val add = list += 2 println("$add") } } } // ??? Scala def main(args: ...): Unit = { val list = MutableList(1) list match { case MutableList(_) => { val add = list += 2 println(s"$add") } } } // ??? List Kotlin puzzlers https://github.com/angryziber/kotlin-puzzlers
  14. Kotlin fun main() { val list = listOf(1) when (list)

    { is MutableList -> { val add = list += 2 println("$add") } } } // UnsupportedOperationException Scala def main(args: ...): Unit = { val list = MutableList(1) list match { case MutableList(_) => { val add = list += 2 println(s"$add") } } } // MutableList(1, 2) List
  15. Kotlin fun main() { val list = listOf(1) // ArrayList!!!

    when (list) { is MutableList -> { val add = list += 2 println("$add") } } } // UnsupportedOperationException Scala def main(args: ...): Unit = { val list = MutableList(1) list match { case MutableList(_) => { val add = list += 2 println(s"$add") } } } // MutableList(1, 2) List KotlinのlistOfはArrayList
  16. Arrow > Functional companion to Kotlin's Standard Library Option Either

    Try NonEmptyList Validated ... ArrowはKotlinの関数型実装をもつライブラリです
  17. Arrow > Functional companion to Kotlin's Standard Library Option Either

    Try NonEmptyList Validated ... Default in Scala
  18. Scala/Cats val list = NonEmptyList.of(1, 2, 3) val tail =

    list ++ List(100) println(s"${tail.exists(_ == 1)}") // ??? println(s"${tail.exists(_ == 100)}") // ??? Check element of NonEmptyList Kotlin/Arrow val list = NonEmptyList.of(1, 2, 3) val tail = list + listOf(100) println("${tail.contains(1)}") // ??? println("${tail.contains(100)}") // ??? CatsとArrowの要素チェック
  19. The same results Kotlin/Arrow val list = NonEmptyList.of(1, 2, 3)

    val tail = list + listOf(100) println("${tail.contains(1)}") // true println("${tail.contains(100)}") // true Scala/Cats val list = NonEmptyList.of(1, 2, 3) val tail = list ++ List(100) println(s"${tail.exists(_ == 1)}") // true println(s"${tail.exists(_ == 100)}") // true 結果は同じ
  20. Cats => Scalaz Kotlin/Arrow val list = NonEmptyList.of(1, 2, 3)

    val tail = list + listOf(100) println("${tail.contains(1)}") // true println("${tail.contains(100)}") // true Scala/Scalaz val list = NonEmptyList(1, 2, 3) val tail = list +: List(100) println(s"${tail.contains(1)}") // ??? println(s"${tail.contains(100)}") // ??? ScalazとArrow
  21. NOT the same results :-o Kotlin/Arrow val list = NonEmptyList.of(1,

    2, 3) val tail = list + listOf(100) println("${tail.contains(1)}") // true println("${tail.contains(100)}") // true Scala/Scalaz val list = NonEmptyList(1, 2, 3) val tail = list +: List(100) println(s"${tail.contains(1)}") // false println(s"${tail.contains(100)}") // treu チョット違う…
  22. What is type? Kotlin/Arrow val list = NonEmptyList.of(1, 2, 3)

    val tail = list + listOf(100) println(tail) // ??? println("${tail.contains(1)}") // true println("${tail.contains(100)}") // true Scala/Scalaz val list = NonEmptyList(1, 2, 3) val tail = list +: List(100) println(tail) // ??? println(s"${tail.contains(1)}") // false println(s"${tail.contains(100)}") // treu tailの型は?
  23. What is type? Kotlin/Arrow val list = NonEmptyList.of(1, 2, 3)

    val tail = list + listOf(100) println(tail) // NonEmptyList(all=[1, 2, 3, 100]) println("${tail.contains(1)}") // true println("${tail.contains(100)}") // true Scala/Scalaz val list = NonEmptyList(1, 2, 3) val tail = list +: List(100) println(tail) // List(NonEmpty[1,2,3], 100) println(s"${tail.contains(1)}") // false println(s"${tail.contains(100)}") // treu ListにCastされている
  24. Wrap-up - Scala and Kotlin have similer syntax - But

    inside is quite different - Take care with similer types (ex. List type design) - Check decompile code 似てるけど中身は結構違う 似ている型は挙動が同じか確認しよう デコンパイルしよう