こんなに違う!ScalaとKotlin

 こんなに違う!ScalaとKotlin

A967476c5855d593710a9a580f6b2aed?s=128

Yuichi Maekawa

June 28, 2019
Tweet

Transcript

  1. 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
  2. 5.

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

    functional programming オブジェクト指向と関数型の統合 Interoperates seamlessly with Java Javaとのシームレスな相互運用
  3. 8.

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

    String = "anonymous" ) 似てる! case class User( name: String = "anonymous" )
  4. 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 めっちゃ似てる!
  5. 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 チョット違う…?
  6. 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) } クラスはどう?
  7. 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... 全然違う…
  8. 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)
  9. 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
  10. 15.

    How is Scala code decompiled? public void main(final String[] args)

    { User user = User$.MODULE$.apply("yuichi"); .MODULE$.println(user.name()); } Scalaをデコンパイルするとシンプル
  11. 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をデコンパイルすると?
  12. 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クラスが自動生成
  13. 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
  14. 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
  15. 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
  16. 24.

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

    Try NonEmptyList Validated ... ArrowはKotlinの関数型実装をもつライブラリです
  17. 25.

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

    Try NonEmptyList Validated ... Default in Scala
  18. 26.
  19. 27.
  20. 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の要素チェック
  21. 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 結果は同じ
  22. 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
  23. 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 チョット違う…
  24. 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の型は?
  25. 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されている
  26. 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 似てるけど中身は結構違う 似ている型は挙動が同じか確認しよう デコンパイルしよう