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

ぼくらがScalaを選ぶ理由〜入門編〜

 ぼくらがScalaを選ぶ理由〜入門編〜

2015/08/27 第3回SpeeeTechPartyでの発表資料
なぜ僕らはScalaを選ぶのか。「最近Scalaって話題になってるけどどうなの?」と気になっている方向けに、営業トークしますw

Hirokazu Nishioka

August 27, 2015
Tweet

More Decks by Hirokazu Nishioka

Other Decks in Programming

Transcript

  1. ΅͘Β͕ScalaΛબͿཧ༝
    ʙೖ໳ฤʙ
    2015-08-27 ୈ3ճSpeeeTechParty
    גࣜձࣾSpeee ੢Ԭ׮݉

    View Slide

  2. ࣗݾ঺հ
    • ੢Ԭ׮݉ʢʹ͓͔͠ ͻΖ͔ͣʣ
    • Speee ΠΤ΢ʔϧ ϦʔυΤϯδχΞ

    αʔόαΠυεϖγϟϦετ
    • twitterɿ@nisshieeorg
    • ޷͖ͳݴޠɿScala
    • ΠΧIDɿnisshieeorg

    View Slide

  3. υϠΝɾɾɾ
    http://markezine.jp/article/detail/22902

    View Slide

  4. ΅͘ͷϓϩάϥϛϯάݴޠྺ
    • ࠷ॳ͸ಠֶͰBasicͱ͔HSPͱ͔Javaͱ͔
    • ࢓ࣄͰ͸JavaɺPHPϝΠϯʹ4೥΄Ͳ
    • ࠷ۙ͸Ruby + Scala
    • ScalaΛ࢝Ίͨͷ͸4೥લ͙Β͍ʢझຯͰʣ

    View Slide

  5. ͳͥScalaΛ࢝Ίͨͷ͔
    • ͍͍ͩͨTwitterͷ͍ͤʢTL͕ͳ͝΍ͩͬͨʣ
    • ؔ਺ܕݴޠͷ࣌୅͕དྷͦ͏ͳงғؾ
    • ࣮͸࠷ॳ͸F#࢝Ίͨ
    • F#޷͖͚ͩͲ.NETͰಈ͍ͯ΋خ͘͠ͳ͔ͬͨ
    • JVMͰಈ͘ͷ͕͋ΔΒ͍͠ʂ → Scala

    View Slide

  6. ScalaͬͯͲΜͳݴޠʁ

    View Slide

  7. ScalaͬͯͲΜͳݴޠʁ
    • ੩తܕ෇͚ؔ਺ܕ + OOP
    • ʮ౷߹ʯͱ͍͏ࢥ૝
    • JVM্Ͱಈ࡞ʢੲ͸.NET΋αϙʔτͯͨ͠ʣ
    • Martin Oderskyڭत࡞ʢ2004 public releaseʣ
    • εΠε࿈๜޻Պେֶڭत
    • খా޷ઌੜ
    Miles Sabin https://www.flickr.com/photos/montpelier/3957416434/

    View Slide

  8. ScalaͬͯͲΜͳݴޠʁ
    • Typesafe Inc.
    • Oderskyڭत+Scala։ൃऀ (2011)
    • Scalaຊମ΍ϥΠϒϥϦͷ։ൃ + αϙʔτ
    • Twitter͕Rails͔ΒScalaʹҠߦ (2008)
    • ࠷ۙͰ͸ࠃ಺࠾༻ࣄྫ΋
    • υϫϯΰɺChatworkɺ͸ͯͳɺCAɺetc and Speee

    View Slide

  9. ඇެࣜϚείοτ

    View Slide

  10. View Slide

  11. ScalaͩͱԿ͕خ͍͠ͷʁ

    View Slide

  12. ྫ͑͹͸ͯͳ͞Μ
    http://songmu.github.io/slides/yapc-asia2015/
    YAPC::Asia Tokyo 2015ͷTalkΑΓ

    View Slide

  13. ؔ਺ʢ਺ֶͷ͓࿩ʣ
    ఆٛҬ ஋Ҭ
    ؔ਺ͷೖྗ஋ͱͯ͠औΓಘΔൣғɿఆٛҬ

    View Slide

  14. ؔ਺ʢϓϩάϥϛϯάͷ͓࿩ʣ
    Ҿ਺ ໭Γ஋

    View Slide

  15. ؔ਺ͷςετ
    Ҿ਺ ໭Γ஋
    (1) ͍Ζ͍ΖͳҾ਺Λ

    ೖΕͯΈΔ
    (2) ݁Ռ͕ૂ͍௨Γ͔

    νΣοΫ

    View Slide

  16. Ͷɺ؆୯Ͱ͠ΐ

    View Slide

  17. ͪΐͬͱ଴ͬͨ

    View Slide

  18. ͋ͳͨͷςετɺେৎ෉ʁ
    Ҿ਺ ໭Γ஋
    ؔ਺ͷఆٛҬΛे෼ʹ໢ཏ͍ͯ͠·͔͢ʁ
    ͱ͍͏͔ͦ΋ͦ΋ɺ͋ͳͨࣗ਎

    ఆٛҬΛͪΌΜͱ೺Ѳ͍ͯ͠·͔͢ʁ
    ʁ

    View Slide

  19. ͋ͳͨͷςετɺେৎ෉ʁ
    Ҿ਺ ໭Γ஋
    ؔ਺ͷ;Δ·͍ʹӨڹΛ༩͑Δೖྗ஋͸

    Ҿ਺͚ͩͰ͔͢ʁ
    Πϯελϯεม਺ʁ
    ؀ڥม਺ʁ
    DBͷ஋ʁ
    ݱࡏ࣌ࠁʁ

    View Slide

  20. ͋ͳͨͷςετɺେৎ෉ʁ
    Ҿ਺ ໭Γ஋
    ؔ਺ͷ;Δ·͍ͷ݁Ռ͕ݱΕΔग़ྗ஋͸

    ໭Γ஋͚ͩͰ͔͢ʁ
    Πϯελϯεม਺ʁ
    ը໘ʁ
    DBͷ஋ʁ
    ྫ֎ʁ

    View Slide

  21. େৎ෉ɺͪΌΜͱ

    શ෦೺Ѳͯ͠ΔΑʂ

    View Slide

  22.        _,,;' '" '' ゛''" ゛' ';;,,
          (rヽ,;''"""''゛゛゛'';, ノr)
          ,;'゛ i _  、_ iヽ゛';,    お前それ、1年後や、仕様変更後や
          ,;'" ''| ヽ・〉 〈・ノ |゙゛ `';, 他人の書いたコードを保守するときでも
          ,;'' "|   ▼   |゙゛ `';, 同じ事言えんの?
          ,;''  ヽ_人_ /  ,;'_
         /シ、  ヽ⌒⌒ /   リ \
        |   "r,, `"'''゙´  ,,ミ゛   |
        |      リ、    ,リ    |
        |   i   ゛r、ノ,,r" i   _|
        |   `ー――----┴ ⌒´ )
        (ヽ  ______ ,, _´)
         (_⌒ ______ ,, ィ
          丁           |
           |           |

    View Slide

  23. ͡Ό͋Ͳ͏͢Δ͔

    View Slide

  24. ఆٛҬΛ໌֬ʹ͢Δ
    • ͜Εͦ͜ܕͷ໾໨
    × υΩϡϝϯτΛಡΊ͹શͯΘ͔Δ
    ̋ γάχνϟΛݟΕ͹શͯΘ͔Δ
    // Scala
    class List[A] {
    def count(p: A => Boolean): Int = ???
    }
    !
    # Ruby (͜Εɺطʹશ෦υΩϡϝϯτɻ࣮ࡍʹ͸ϝιου಺Ͱif෼ذ͍ͯ͠Δ)
    count -> Integer
    count(item) -> Integer
    count {|obj| ... } -> Integer

    View Slide

  25. sealed trait, case class
    • ࣗ࡞ͷܕ΋ఆٛҬΛ໌֬ʹ͢Δ
    sealed trait Item
    !
    sealed trait Weapon extends Item
    case class Sword(power: Int) extends Weapon
    !
    sealed trait Medicine extends Item
    case object Antidote extends Medicine
    !
    // ——————————————————————————
    !
    def buy(item: Item)
    def equip(weapon: Weapon)
    def take(medicine: Medicine)

    View Slide

  26. ʢ༨ஊʣ໢ཏੑνΣοΫ
    def buy(item: Item) = item match {
    case sword: Sword => ???
    case Antidote => ???
    }
    // —————————————————————————-
    !
    def buy(item: Item) = item match {
    case sword: Sword => ???
    }
    // ↑ ίϯύΠϧΤϥʔ
    :29: warning: match may not be exhaustive.
    It would fail on the following input: Antidote
    def buy(item: Item) = item match {
    ^
    error: No warnings can be incurred under -Xfatal-warnings.

    View Slide

  27. ೖྗ஋ɺग़ྗ஋ͷൣғ
    Ҿ਺ ໭Γ஋
    Πϯελϯεม਺ʁ
    ؀ڥม਺ʁ
    DBͷ஋ʁ
    ݱࡏ࣌ࠁʁ
    Πϯελϯεม਺ʁ
    ը໘ʁ
    DBͷ஋ʁ
    ྫ֎ʁ
    • ͍͍ͩͨ೺Ѳ͖͠Ε͍ͯͳͯ͘όάΔʢܦݧஊʣ
    • ʮ೺ѲͰ͖Δʯͱ͍͏ݬ૝͸ࣺͯͨ΄͏͕ྑ͍
    4DBMBʹݶΒͳ͍Ұൠతͳ࿩

    View Slide

  28. ೖྗ஋ɺग़ྗ஋Λݶఆ
    Ҿ਺ ໭Γ஋
    Πϯελϯεม਺ʁ
    ؀ڥม਺ʁ
    DBͷ஋ʁ
    ݱࡏ࣌ࠁʁ
    Πϯελϯεม਺ʁ
    ը໘ʁ
    DBͷ஋ʁ
    ྫ֎ʁ
    • Ҿ਺͚ͩͰؔ਺ͷ;Δ·͍͕ܾ·Δʢࢀরಁ໌ੑʣ
    • ໭Γ஋Ҏ֎ͷӨڹʢ෭࡞༻ʣ͕ͳ͍

    View Slide

  29. ࢀরಁ໌Ͱ෭࡞༻ͷͳ͍ؔ਺
    • ඞཁͳ৘ใ͸શͯҾ਺ʹ
    • ݁Ռ͸શͯ໭Γ஋ʹʢྫ֎Λ࢖Θͳ͍ʣ
    • ʮͱ͸ݴ͑ɺDBͷಡΈॻ͖͠ͳ͍Θ͚ʹ͸ʯ
    • ʮDBΞΫηεͷ͋Δؔ਺܈ʯΛ੾Γ཭͢
    • IOϞφυͱ͔

    View Slide

  30. ScalaͳΒ
    • ͜͏͍͏ͷ͕΍Γ΍͍͢Αʂ

    View Slide

  31. implicit parameter
    ஫ʣ؀ڥ৘ใͷimplicit parameterԽ͸ࢍ൱͋Γ·͢
    def hoge(args: Args, env: Env): Res = ???
    def fuga(args: Args, env: Env): Res = hoge(args, env)
    !
    fuga(args, env)
    // ؔ਺ίʔϧ࣌ʹຖճ؀ڥ৘ใΛҾ਺ʹ౉͢ͷ͸μϧ͍
    !
    // ——————————————————————————————————
    def hoge(args: Args)(implicit env: Env) = ???
    def fuga(args: Args)(implicit env: Env) = hoge(args)
    !
    implicit val env: Env = ???
    fuga(args)

    View Slide

  32. Option
    • ஋͕͋Δʢ੒ޭͯ͠ɺ஋͕ฦΔʣ
    • ஋͕ͳ͍ʢࣦഊʣ
    sealed trait Option[A]
    case class Some[A](a: A) extends Option[A]
    case object None extends Option[Nothing]
    !
    // ———————————————————————————-
    !
    class List[A] {
    def find(p: A => Boolean): Option[A] = ???
    }

    View Slide

  33. ໭͞ΕͨOptionΛѻ͏
    val found: Option[A] = aList.find(condition)
    !
    // BAD (ݹ͖ྑ͖nullνΣοΫͱҰॹ)
    if (found.isDefined) {
    val a = found.get
    ???
    }
    !
    // So so ... (લड़ͷ໢ཏੑνΣοΫ΋૸Δ)
    found match {
    case Some(a) => ???
    case None => ???
    }

    View Slide

  34. Optionʹؔ਺Λ౉͢
    // GOOD!!
    // aToB: A => B
    found.map(aToB) // => Option[B]
    !
    // failableAToB: A => Option[B]
    found.flatMap(failableAToB) // => Option[B]
    !
    for {
    a <- found
    b <- failableAToB(a)
    c <- failableBToC(b)
    d <- failableCToD(c)
    } yield dToE(d) // => Option[E]

    View Slide

  35. EitherͰʮࣦഊཧ༝ʯΛฦ͢
    sealed trait Either[E, A]
    case class Right[A](a: A) extends Either[Nothing, A]
    case class Left[E](e: E) extends Either[E, Nothing]
    !
    // ʮࣦഊʯͷఆٛ
    sealed trait EquipFailure
    case class JobMismatch(j: Job, w: Weapon)
    extends EquipFailure
    case class LevelShortage(l: Level, w: Weapon)
    extends EquipFailure
    !
    // EitherΛฦ͢
    def equip(weapon: Weapon): Either[EquipFailure, Status] = ???

    View Slide

  36. ໭͞ΕͨEitherΛѻ͏
    equip(weapon).fold({
    case JobMismatch(j, w) => ???
    case LevelShortage(l, w) => ???
    }, { status =>
    ???
    })

    View Slide

  37. ཁ͢Δʹ
    Կ͕ݴ͍͔͔ͨͬͨ

    View Slide

  38. γάχνϟͰશͯ෼͔Δ
    • ໋໊Λ͕Μ͹Δ ← ඞཁ͕ͩɺݶք͕͋Δ
    • γάχνϟʹදΕͳ͍΋ͷ͸࢖Θͳ͍
    • ʮܕͷ஌ࣝʯΛར༻͢Δʢʮܕ͸υΩϡϝϯτʯʣ
    • ܕͰ͔ͬͪΓݻΊΔ͜ͱ͸طଘݴޠͰ΋Ͱ͖͔ͨ΋
    ͠Εͳ͍͕ɺѻ͍ͮΒ͔ͬͨ

    → Ͱ΋ɺScalaͳΒָʹͰ͖ΔΑʂ


    Ұ



    ͳ

    εϥ
    Π
    υ

    View Slide

  39. ͕࣌ؒ͋Ε͹

    Scalaͷ໘ന͍ػೳ঺հ

    View Slide

  40. String Interpolation
    • ଞͷݴޠͩͱʮม਺ల։ʯͱ͔ݴΘΕΔ΍ͭ
    !
    !
    • ʮsʯͷଞʹʮfʯ΋͋Δʢิؒࢠʣ
    val name: String = "Nishioka"
    val age: Int = 28
    val s: String = s"${name}͘Μ${age}͍͞"
    // => Nishioka͘Μ28͍͞
    val better: String = f"${name}%s͘Μ${age}%X͍͞"
    // => Nishioka͘Μ1C͍͞

    View Slide

  41. String Interpolation
    • ิؒࢠ͸ࣗ෼Ͱ࡞Δ͜ͱ΋Ͱ͖Δʂ
    • ྫɿScalikeJDBCʢhttp://scalikejdbc.org/ʣ
    object EmployeeRepository {

    def findBy(dep: Department)(implicit ses: DBSession) =
    sql"""
    select
    *
    from
    employees
    where
    department_id = ${dep.id}
    """.map(extract).list.apply
    }

    View Slide

  42. lazy val
    • ஗ԆධՁʢ࠷ॳʹ࢖ΘΕͨͱ͖ʹॳظԽʣ
    scala> lazy val s: String = {
    | println("initialized")
    | "a string"
    | }
    s: String =
    !
    scala> println(s)
    initialized
    a string
    !
    scala> println(s)
    a string

    View Slide

  43. Future
    • ϊϯϒϩοΩϯάʂඇಉظʂ
    val f: Future[Result] = Future { longTimeFunc() }
    // ↑ ϊϯϒϩοΩϯά
    !
    f onComplete {
    case Success(result) => ???
    case Failure(thrown) => ???
    }
    !
    f onSuccess { case result => ??? }
    f onFailure { case thrown => ??? }

    View Slide

  44. Futureͷ߹੒
    val fa: Future[A] = Future { ??? }
    !
    // aToB: A => B
    fa.map(aToB) // => Future[B]
    !
    // longTimeAToB: A => Future[B]
    fa.flatMap(longTimeAToB) // => Future[B]
    !
    for {
    a <- fa
    b <- fb
    c <- longTimeC(a, b)
    } yield cToD(c) // => Future[D]

    View Slide

  45. ΞυϗοΫͳػೳ௥Ճ
    • ݺͼग़࣌͠ʹ͸ʮͦͷػೳ௥Ճ͞ΕͯΔ͔ʯ

    νΣοΫ͕ίϯύΠϧ࣌ʹ૸Δ ← ܕ҆શ
    implicit class StringExt(val self: String)
    extends AnyVal {
    def suddenDeath = ???
    }
    !
    scala> "ಥવͷࢮ".suddenDeath
    res9: String =
    ʊਓਓਓਓਓਓʊ
    ʼɹಥવͷࢮɹʻ
    ʉY^Y^Y^Y^Yʉ

    View Slide

  46. ଞʹ΋ʮ͜Μͳػೳ͋Δʁʯ

    ͱ͔͋Ε͹ڍ͍͛ͯͩ͘͞ʂ

    View Slide

  47. ·ͱΊ

    View Slide

  48. Scalaͷྑ͍ͱ͜Ζ
    • ඼࣭Λॏࢹͨ͠։ൃ
    • ܕ͸υΩϡϝϯτ
    • ίϯύΠϧ͸ςετ
    • ΨνΨνʹݻΊͨ඼࣭ͷ࣮ݱΛ

    ݴޠ͕ڧྗʹαϙʔτͯ͘͠ΕΔ
    • ϞμϯͳLLʹ΋Ҿ͚ΛͱΒͳ͍දݱྗ
    Speee Engineer’s Policy “COMPASS” ΑΓ

    View Slide

  49. ͝੩ௌ͋Γ͕ͱ͏͍͟͝·ͨ͠

    View Slide