$30 off During Our Annual Pro Sale. View Details »

こんなに違う!ScalaとKotlin

 こんなに違う!ScalaとKotlin

Yuichi Maekawa

June 28, 2019
Tweet

More Decks by Yuichi Maekawa

Other Decks in Programming

Transcript

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

    View Slide

  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

    View Slide

  3. Scala == Kotlin
    ???
    ScalaとKotlinは同じ?

    View Slide

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

    View Slide

  5. Scala philosophy / Scalaの哲学
    Scalable language
    スケーラブルな言語
    Unifies object-oriented and functional programming
    オブジェクト指向と関数型の統合
    Interoperates seamlessly with Java
    Javaとのシームレスな相互運用

    View Slide

  6. Kotlin philosophy / Kotlinの哲学
    健全性よりも

    View Slide

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

    View Slide

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

    View Slide

  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
    めっちゃ似てる!

    View Slide

  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
    チョット違う…?

    View Slide

  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)
    } クラスはどう?

    View Slide

  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...
    全然違う…

    View Slide

  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)

    View Slide

  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

    View Slide

  15. How is Scala code decompiled?
    public void main(final String[] args) {
    User user = User$.MODULE$.apply("yuichi");
    .MODULE$.println(user.name());
    }
    Scalaをデコンパイルするとシンプル

    View Slide

  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をデコンパイルすると?

    View Slide

  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クラスが自動生成

    View Slide

  18. How to show decompile code?(IntelliJ IDEA)
    IDEAでデコンパイル

    View Slide

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

    View Slide

  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

    View Slide

  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

    View Slide

  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

    View Slide

  23. Kotlin cannot FP
    ???
    Kotlinでは関数型ができないでしょうか

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  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の要素チェック

    View Slide

  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
    結果は同じ

    View Slide

  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

    View Slide

  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
    チョット違う…

    View Slide

  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の型は?

    View Slide

  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されている

    View Slide

  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
    似てるけど中身は結構違う
    似ている型は挙動が同じか確認しよう
    デコンパイルしよう

    View Slide

  35. Thank you!
    Have a nice Scala & Kotlin!
    _kaelaela / Alp, Inc.

    View Slide