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

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

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

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

C48758d8162582b770092002effb7dff?s=128

Hirokazu Nishioka

August 27, 2015
Tweet

Transcript

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

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

    twitterɿ@nisshieeorg • ޷͖ͳݴޠɿScala • ΠΧIDɿnisshieeorg
  3. υϠΝɾɾɾ http://markezine.jp/article/detail/22902

  4. ΅͘ͷϓϩάϥϛϯάݴޠྺ • ࠷ॳ͸ಠֶͰBasicͱ͔HSPͱ͔Javaͱ͔ • ࢓ࣄͰ͸JavaɺPHPϝΠϯʹ4೥΄Ͳ • ࠷ۙ͸Ruby + Scala •

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

    JVMͰಈ͘ͷ͕͋ΔΒ͍͠ʂ → Scala
  6. ScalaͬͯͲΜͳݴޠʁ

  7. ScalaͬͯͲΜͳݴޠʁ • ੩తܕ෇͚ؔ਺ܕ + OOP • ʮ౷߹ʯͱ͍͏ࢥ૝ • JVM্Ͱಈ࡞ʢੲ͸.NET΋αϙʔτͯͨ͠ʣ •

    Martin Oderskyڭत࡞ʢ2004 public releaseʣ • εΠε࿈๜޻Պେֶڭत • খా޷ઌੜ Miles Sabin https://www.flickr.com/photos/montpelier/3957416434/
  8. ScalaͬͯͲΜͳݴޠʁ • Typesafe Inc. • Oderskyڭत+Scala։ൃऀ (2011) • Scalaຊମ΍ϥΠϒϥϦͷ։ൃ +

    αϙʔτ • Twitter͕Rails͔ΒScalaʹҠߦ (2008) • ࠷ۙͰ͸ࠃ಺࠾༻ࣄྫ΋ • υϫϯΰɺChatworkɺ͸ͯͳɺCAɺetc and Speee
  9. ඇެࣜϚείοτ

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

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

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

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

  15. ؔ਺ͷςετ Ҿ਺ ໭Γ஋ (1) ͍Ζ͍ΖͳҾ਺Λ
 ೖΕͯΈΔ (2) ݁Ռ͕ૂ͍௨Γ͔
 νΣοΫ

  16. Ͷɺ؆୯Ͱ͠ΐ

  17. ͪΐͬͱ଴ͬͨ

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

  19. ͋ͳͨͷςετɺେৎ෉ʁ Ҿ਺ ໭Γ஋ ؔ਺ͷ;Δ·͍ʹӨڹΛ༩͑Δೖྗ஋͸
 Ҿ਺͚ͩͰ͔͢ʁ Πϯελϯεม਺ʁ ؀ڥม਺ʁ DBͷ஋ʁ ݱࡏ࣌ࠁʁ

  20. ͋ͳͨͷςετɺେৎ෉ʁ Ҿ਺ ໭Γ஋ ؔ਺ͷ;Δ·͍ͷ݁Ռ͕ݱΕΔग़ྗ஋͸
 ໭Γ஋͚ͩͰ͔͢ʁ Πϯελϯεม਺ʁ ը໘ʁ DBͷ஋ʁ ྫ֎ʁ

  21. େৎ෉ɺͪΌΜͱ
 શ෦೺Ѳͯ͠ΔΑʂ

  22.        _,,;' '" '' ゛''" ゛' ';;,,       (rヽ,;''"""''゛゛゛'';, ノr)       ,;'゛ i

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

  24. ఆٛҬΛ໌֬ʹ͢Δ • ͜Εͦ͜ܕͷ໾໨ × υΩϡϝϯτΛಡΊ͹શͯΘ͔Δ ̋ γάχνϟΛݟΕ͹શͯΘ͔Δ // Scala class

    List[A] { def count(p: A => Boolean): Int = ??? } ! # Ruby (͜Εɺطʹશ෦υΩϡϝϯτɻ࣮ࡍʹ͸ϝιου಺Ͱif෼ذ͍ͯ͠Δ) count -> Integer count(item) -> Integer count {|obj| ... } -> Integer
  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)
  26. ʢ༨ஊʣ໢ཏੑνΣοΫ def buy(item: Item) = item match { case sword:

    Sword => ??? case Antidote => ??? } // —————————————————————————- ! def buy(item: Item) = item match { case sword: Sword => ??? } // ↑ ίϯύΠϧΤϥʔ <console>: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.
  27. ೖྗ஋ɺग़ྗ஋ͷൣғ Ҿ਺ ໭Γ஋ Πϯελϯεม਺ʁ ؀ڥม਺ʁ DBͷ஋ʁ ݱࡏ࣌ࠁʁ Πϯελϯεม਺ʁ ը໘ʁ DBͷ஋ʁ

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

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

    IOϞφυͱ͔
  30. ScalaͳΒ • ͜͏͍͏ͷ͕΍Γ΍͍͢Αʂ

  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)
  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] = ??? }
  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 => ??? }
  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]
  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] = ???
  36. ໭͞ΕͨEitherΛѻ͏ equip(weapon).fold({ case JobMismatch(j, w) => ??? case LevelShortage(l, w)

    => ??? }, { status => ??? })
  37. ཁ͢Δʹ Կ͕ݴ͍͔͔ͨͬͨ

  38. γάχνϟͰશͯ෼͔Δ • ໋໊Λ͕Μ͹Δ ← ඞཁ͕ͩɺݶք͕͋Δ • γάχνϟʹදΕͳ͍΋ͷ͸࢖Θͳ͍ • ʮܕͷ஌ࣝʯΛར༻͢Δʢʮܕ͸υΩϡϝϯτʯʣ •

    ܕͰ͔ͬͪΓݻΊΔ͜ͱ͸طଘݴޠͰ΋Ͱ͖͔ͨ΋ ͠Εͳ͍͕ɺѻ͍ͮΒ͔ͬͨ
 → Ͱ΋ɺScalaͳΒָʹͰ͖ΔΑʂ ࠓ ೔ Ұ ൪ େ ࣄ ͳ 
 εϥ Π υ
  39. ͕࣌ؒ͋Ε͹
 Scalaͷ໘ന͍ػೳ঺հ

  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͍͞
  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 }
  42. lazy val • ஗ԆධՁʢ࠷ॳʹ࢖ΘΕͨͱ͖ʹॳظԽʣ scala> lazy val s: String =

    { | println("initialized") | "a string" | } s: String = <lazy> ! scala> println(s) initialized a string ! scala> println(s) a string
  43. Future • ϊϯϒϩοΩϯάʂඇಉظʂ val f: Future[Result] = Future { longTimeFunc()

    } // ↑ ϊϯϒϩοΩϯά ! f onComplete { case Success(result) => ??? case Failure(thrown) => ??? } ! f onSuccess { case result => ??? } f onFailure { case thrown => ??? }
  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]
  45. ΞυϗοΫͳػೳ௥Ճ • ݺͼग़࣌͠ʹ͸ʮͦͷػೳ௥Ճ͞ΕͯΔ͔ʯ
 νΣοΫ͕ίϯύΠϧ࣌ʹ૸Δ ← ܕ҆શ implicit class StringExt(val self:

    String) extends AnyVal { def suddenDeath = ??? } ! scala> "ಥવͷࢮ".suddenDeath res9: String = ʊਓਓਓਓਓਓʊ ʼɹಥવͷࢮɹʻ ʉY^Y^Y^Y^Yʉ
  46. ଞʹ΋ʮ͜Μͳػೳ͋Δʁʯ
 ͱ͔͋Ε͹ڍ͍͛ͯͩ͘͞ʂ

  47. ·ͱΊ

  48. Scalaͷྑ͍ͱ͜Ζ • ඼࣭Λॏࢹͨ͠։ൃ • ܕ͸υΩϡϝϯτ • ίϯύΠϧ͸ςετ • ΨνΨνʹݻΊͨ඼࣭ͷ࣮ݱΛ
 ݴޠ͕ڧྗʹαϙʔτͯ͘͠ΕΔ

    • ϞμϯͳLLʹ΋Ҿ͚ΛͱΒͳ͍දݱྗ Speee Engineer’s Policy “COMPASS” ΑΓ
  49. ͝੩ௌ͋Γ͕ͱ͏͍͟͝·ͨ͠