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

こんなに違う!ScalaとKotlin

Sponsored · SiteGround - Reliable hosting with speed, security, and support you can count on.

 こんなに違う!ScalaとKotlin

Avatar for Yuichi Maekawa

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