Upgrade to PRO for Only $50/Year—Limited-Time Offer! 🔥

ぼくらが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ͬͯͲΜͳݴޠʁ • ੩తܕ෇͚ؔ਺ܕ + OOP • ʮ౷߹ʯͱ͍͏ࢥ૝ • JVM্Ͱಈ࡞ʢੲ͸.NET΋αϙʔτͯͨ͠ʣ •

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

    αϙʔτ • Twitter͕Rails͔ΒScalaʹҠߦ (2008) • ࠷ۙͰ͸ࠃ಺࠾༻ࣄྫ΋ • υϫϯΰɺChatworkɺ͸ͯͳɺCAɺetc and Speee
  3.        _,,;' '" '' ゛''" ゛' ';;,,       (rヽ,;''"""''゛゛゛'';, ノr)       ,;'゛ i

    _  、_ iヽ゛';,    お前それ、1年後や、仕様変更後や       ,;'" ''| ヽ・〉 〈・ノ |゙゛ `';, 他人の書いたコードを保守するときでも       ,;'' "|   ▼   |゙゛ `';, 同じ事言えんの?       ,;''  ヽ_人_ /  ,;'_      /シ、  ヽ⌒⌒ /   リ \     |   "r,, `"'''゙´  ,,ミ゛   |     |      リ、    ,リ    |     |   i   ゛r、ノ,,r" i   _|     |   `ー――----┴ ⌒´ )     (ヽ  ______ ,, _´)      (_⌒ ______ ,, ィ       丁           |        |           |
  4. ఆٛҬΛ໌֬ʹ͢Δ • ͜Εͦ͜ܕͷ໾໨ × υΩϡϝϯτΛಡΊ͹શͯΘ͔Δ ̋ γάχνϟΛݟΕ͹શͯΘ͔Δ // Scala class

    List[A] { def count(p: A => Boolean): Int = ??? } ! # Ruby (͜Εɺطʹશ෦υΩϡϝϯτɻ࣮ࡍʹ͸ϝιου಺Ͱif෼ذ͍ͯ͠Δ) count -> Integer count(item) -> Integer count {|obj| ... } -> Integer
  5. 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)
  6. ʢ༨ஊʣ໢ཏੑνΣοΫ 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.
  7. ೖྗ஋ɺग़ྗ஋ͷൣғ Ҿ਺ ໭Γ஋ Πϯελϯεม਺ʁ ؀ڥม਺ʁ DBͷ஋ʁ ݱࡏ࣌ࠁʁ Πϯελϯεม਺ʁ ը໘ʁ DBͷ஋ʁ

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

    ྫ֎ʁ • Ҿ਺͚ͩͰؔ਺ͷ;Δ·͍͕ܾ·Δʢࢀরಁ໌ੑʣ • ໭Γ஋Ҏ֎ͷӨڹʢ෭࡞༻ʣ͕ͳ͍
  9. 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)
  10. 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] = ??? }
  11. ໭͞Εͨ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 => ??? }
  12. 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]
  13. 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] = ???
  14. γάχνϟͰશͯ෼͔Δ • ໋໊Λ͕Μ͹Δ ← ඞཁ͕ͩɺݶք͕͋Δ • γάχνϟʹදΕͳ͍΋ͷ͸࢖Θͳ͍ • ʮܕͷ஌ࣝʯΛར༻͢Δʢʮܕ͸υΩϡϝϯτʯʣ •

    ܕͰ͔ͬͪΓݻΊΔ͜ͱ͸طଘݴޠͰ΋Ͱ͖͔ͨ΋ ͠Εͳ͍͕ɺѻ͍ͮΒ͔ͬͨ
 → Ͱ΋ɺScalaͳΒָʹͰ͖ΔΑʂ ࠓ ೔ Ұ ൪ େ ࣄ ͳ 
 εϥ Π υ
  15. 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͍͞
  16. 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 }
  17. 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
  18. Future • ϊϯϒϩοΩϯάʂඇಉظʂ val f: Future[Result] = Future { longTimeFunc()

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

    String) extends AnyVal { def suddenDeath = ??? } ! scala> "ಥવͷࢮ".suddenDeath res9: String = ʊਓਓਓਓਓਓʊ ʼɹಥવͷࢮɹʻ ʉY^Y^Y^Y^Yʉ