Slide 1

Slide 1 text

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

Slide 2

Slide 2 text

ࣗݾ঺հ • ੢Ԭ׮݉ʢʹ͓͔͠ ͻΖ͔ͣʣ • Speee ΠΤ΢ʔϧ ϦʔυΤϯδχΞ
 αʔόαΠυεϖγϟϦετ • twitterɿ@nisshieeorg • ޷͖ͳݴޠɿScala • ΠΧIDɿnisshieeorg

Slide 3

Slide 3 text

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

Slide 4

Slide 4 text

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

Slide 5

Slide 5 text

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

Slide 6

Slide 6 text

ScalaͬͯͲΜͳݴޠʁ

Slide 7

Slide 7 text

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

Slide 8

Slide 8 text

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

Slide 9

Slide 9 text

ඇެࣜϚείοτ

Slide 10

Slide 10 text

No content

Slide 11

Slide 11 text

ScalaͩͱԿ͕خ͍͠ͷʁ

Slide 12

Slide 12 text

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

Slide 13

Slide 13 text

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

Slide 14

Slide 14 text

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

Slide 15

Slide 15 text

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

Slide 16

Slide 16 text

Ͷɺ؆୯Ͱ͠ΐ

Slide 17

Slide 17 text

ͪΐͬͱ଴ͬͨ

Slide 18

Slide 18 text

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

Slide 19

Slide 19 text

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

Slide 20

Slide 20 text

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

Slide 21

Slide 21 text

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

Slide 22

Slide 22 text

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

Slide 23

Slide 23 text

͡Ό͋Ͳ͏͢Δ͔

Slide 24

Slide 24 text

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

Slide 25

Slide 25 text

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)

Slide 26

Slide 26 text

ʢ༨ஊʣ໢ཏੑνΣοΫ 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.

Slide 27

Slide 27 text

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

Slide 28

Slide 28 text

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

Slide 29

Slide 29 text

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

Slide 30

Slide 30 text

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

Slide 31

Slide 31 text

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)

Slide 32

Slide 32 text

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] = ??? }

Slide 33

Slide 33 text

໭͞Εͨ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 => ??? }

Slide 34

Slide 34 text

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]

Slide 35

Slide 35 text

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] = ???

Slide 36

Slide 36 text

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

Slide 37

Slide 37 text

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

Slide 38

Slide 38 text

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

Slide 39

Slide 39 text

͕࣌ؒ͋Ε͹
 Scalaͷ໘ന͍ػೳ঺հ

Slide 40

Slide 40 text

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͍͞

Slide 41

Slide 41 text

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 }

Slide 42

Slide 42 text

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

Slide 43

Slide 43 text

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

Slide 44

Slide 44 text

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]

Slide 45

Slide 45 text

ΞυϗοΫͳػೳ௥Ճ • ݺͼग़࣌͠ʹ͸ʮͦͷػೳ௥Ճ͞ΕͯΔ͔ʯ
 νΣοΫ͕ίϯύΠϧ࣌ʹ૸Δ ← ܕ҆શ implicit class StringExt(val self: String) extends AnyVal { def suddenDeath = ??? } ! scala> "ಥવͷࢮ".suddenDeath res9: String = ʊਓਓਓਓਓਓʊ ʼɹಥવͷࢮɹʻ ʉY^Y^Y^Y^Yʉ

Slide 46

Slide 46 text

ଞʹ΋ʮ͜Μͳػೳ͋Δʁʯ
 ͱ͔͋Ε͹ڍ͍͛ͯͩ͘͞ʂ

Slide 47

Slide 47 text

·ͱΊ

Slide 48

Slide 48 text

Scalaͷྑ͍ͱ͜Ζ • ඼࣭Λॏࢹͨ͠։ൃ • ܕ͸υΩϡϝϯτ • ίϯύΠϧ͸ςετ • ΨνΨνʹݻΊͨ඼࣭ͷ࣮ݱΛ
 ݴޠ͕ڧྗʹαϙʔτͯ͘͠ΕΔ • ϞμϯͳLLʹ΋Ҿ͚ΛͱΒͳ͍දݱྗ Speee Engineer’s Policy “COMPASS” ΑΓ

Slide 49

Slide 49 text

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