こんなに違う!ScalaとKotlin

 こんなに違う!ScalaとKotlin

A967476c5855d593710a9a580f6b2aed?s=128

Yuichi Maekawa

June 28, 2019
Tweet

Transcript

  1. What a difference! <-Scala & Kotlin-> @kaelaela

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

    DDD with Eff Twitter: _kaelaela GitHub: kaelaela Scala: helf a year Kotlin: 2.5 years
  3. Scala == Kotlin ??? ScalaとKotlinは同じ?

  4. Kotlin extends Scala ??? KotlinはScalaを真似して作られた?

  5. Scala philosophy / Scalaの哲学 Scalable language スケーラブルな言語 Unifies object-oriented and

    functional programming オブジェクト指向と関数型の統合 Interoperates seamlessly with Java Javaとのシームレスな相互運用
  6. Kotlin philosophy / Kotlinの哲学 健全性よりも

  7. Scala != Kotlin ??? ScalaとKotlinは全然違う?

  8. Scala and Kotlin are similar data class User( var name:

    String = "anonymous" ) 似てる! case class User( name: String = "anonymous" )
  9. 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 めっちゃ似てる!
  10. 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 チョット違う…?
  11. 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) } クラスはどう?
  12. 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... 全然違う…
  13. 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)
  14. 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
  15. How is Scala code decompiled? public void main(final String[] args)

    { User user = User$.MODULE$.apply("yuichi"); .MODULE$.println(user.name()); } Scalaをデコンパイルするとシンプル
  16. 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をデコンパイルすると?
  17. 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クラスが自動生成
  18. How to show decompile code?(IntelliJ IDEA) IDEAでデコンパイル

  19. How to show decompile code?(AS) ASでデコンパイル

  20. 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
  21. 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
  22. 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
  23. Kotlin cannot FP ??? Kotlinでは関数型ができないでしょうか

  24. Arrow > Functional companion to Kotlin's Standard Library Option Either

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

    Try NonEmptyList Validated ... Default in Scala
  26. Arrow > Functional companion to Kotlin's Standard Library Option Either

    Try NonEmptyList Validated ... Cats/Scalaz
  27. Arrow > Functional companion to Kotlin's Standard Library Option Either

    Try NonEmptyList Validated ... Cats/Scalaz
  28. 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の要素チェック
  29. 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 結果は同じ
  30. 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
  31. 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 チョット違う…
  32. 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の型は?
  33. 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されている
  34. 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 似てるけど中身は結構違う 似ている型は挙動が同じか確認しよう デコンパイルしよう
  35. Thank you! Have a nice Scala & Kotlin! _kaelaela /

    Alp, Inc.