Slide 1

Slide 1 text

Scala ZIOをバッチ処理で使ってみた
 リチャード 伊真岡
 マーベリック株式会社


Slide 2

Slide 2 text

関数型の最大のメリット(の一つ)はtestability! ①
 “Functional programming ordinarily gives us the incredible ability to easily test our software.” Beautiful, Simple, Testable Functional Effects for Scala JOHN A DE GOES (blog) Feb, 2019 John De Goes氏 ZIO作者

Slide 3

Slide 3 text

関数型の最大のメリット(の一つ)はtestability! ②
 “I would argue that the whole point of functional programming in general is testing” Free as in Monads - ETE 2017 Daniel Spiewak氏

Slide 4

Slide 4 text

純粋関数はtestabilityが高い
 input 1 input 2 output

Slide 5

Slide 5 text

純粋関数はtestabilityが高い
 test input 1 test input 2 output expected output assert!

Slide 6

Slide 6 text

副作用はテストが難しい
 Database
 File
 HTTP


Slide 7

Slide 7 text

副作用を含むコード
 副作用
 純粋関数呼び出し


Slide 8

Slide 8 text

テストしづらい...
 そこで関数型のテクニックを使う!


Slide 9

Slide 9 text

descriptionとinterpreterの分離
 val programDescription = for { … <- queryDatabase(…) … <- callHttpService(…) … <- doSomeMagic(…) } yield finalResult def main(args: Array[String]): Unit = { interpreter.unsafeRun(programDescription) }

Slide 10

Slide 10 text

descriptionとinterpreterの分離
 val programDescription = for { … <- queryDatabase(…) … <- callHttpService(…) … <- doSomeMagic(…) } yield finalResult def main(args: Array[String]): Unit = { interpreter.unsafeRun(programDescription) }

Slide 11

Slide 11 text

descriptionとinterpreterの分離
 val programDescription = for { … <- queryDatabase(…) … <- callHttpService(…) … <- doSomeMagic(…) } yield finalResult def main(args: Array[String]): Unit = { interpreter.unsafeRun(programDescription) } tree構造
 副作用


Slide 12

Slide 12 text

descriptionとinterpreterの分離
 ● この流れに沿うテクニックとしてfree-monad, tagless-finalなどがある ● しかし...

Slide 13

Slide 13 text

John De Goes氏のThe Death of Tagless Finalより
 https://skillsmatter.com/skillscasts/13247-scala-matters

Slide 14

Slide 14 text

John De Goes氏のThe Death of Tagless Finalより
 https://skillsmatter.com/skillscasts/13247-scala-matters

Slide 15

Slide 15 text

副作用同士はtestで比較できない
 input 1 input 2 description expected description assert!??? e.g. println

Slide 16

Slide 16 text

JOHN A DE GOES - The False Hope of Managing Effects with Tagless-Final in Scala 


Slide 17

Slide 17 text

Scala ZIOの方がtagless finalよりイイ?
 ● testabilityの向上 ● とくに非関数型プログラマになじみやすい(らしい) ○ -> ZIO自体の開発動機のひとつ (ZIO作者談)


Slide 18

Slide 18 text

Scala ZIOをバッチ処理で使ってみた


Slide 19

Slide 19 text

ZIOの戻り値型
 ZIO[R, E, A] ● R - Environment Type. ● E - Failure Type. ● A - Success Type.

Slide 20

Slide 20 text

ZIOの戻り値型
 ZIO[R, E, A] ● R - Environment Type. ● E - Failure Type. ● A - Success Type. <- Exception, Error

Slide 21

Slide 21 text

ZIOの戻り値型
 ZIO[R, E, A] ● R - Environment Type. ● E - Failure Type. ● A - Success Type. <- DI components, DB, Config, ThreadPool

Slide 22

Slide 22 text

No content

Slide 23

Slide 23 text

これがCirquaだ!


Slide 24

Slide 24 text

これがCirquaだ!


Slide 25

Slide 25 text

これがCirquaだ!


Slide 26

Slide 26 text

これがCirquaだ!


Slide 27

Slide 27 text

これがCirquaだ!
 独立している!!

Slide 28

Slide 28 text

ZIOの戻り値型
 ZIO[R, E, A] ● R - Environment Type. ● E - Failure Type. ● A - Success Type. <- DI components, DB, Config, ThreadPool

Slide 29

Slide 29 text

ZIOでのDI手順例: DIするコンポーネントを特定
 Config S3 Logger Athena Database etc

Slide 30

Slide 30 text

trait S3Service { def getFromS3(...): ZIO[Any, Throwable, S3Result] } S3 例:
 cake pattern


Slide 31

Slide 31 text

trait S3Service { def getFromS3(...): ZIO[Any, Throwable, S3Result] } S3 trait S3Component { val service: S3Service }

Slide 32

Slide 32 text

trait S3Service { def getFromS3(...): ZIO[Any, Throwable, S3Result] } S3 trait S3Component { val service: S3Service } object S3ProductionComponent extends S3Component { val service: S3.Service = ... }

Slide 33

Slide 33 text

trait S3Service { def getFromS3(...): ZIO[Any, Throwable, S3Result] } S3 trait S3Component { val service: S3Service } object S3ProductionComponent extends S3Component { val service: S3.Service = ... } object S3TestComponent extends S3Component { val service: S3.Service = ... }

Slide 34

Slide 34 text

trait MainComponent extends S3Component with AthenaComponent with DatabaseComponent with ConfigComponent with LoggerComponent with … … cake pattern
 
 どっちかというとおまんじゅうに見える 


Slide 35

Slide 35 text

\アッタカイヨー/


Slide 36

Slide 36 text

CirquaでのZIO利用例
 def run(args: List[String]) = { _ <- logger.info(...) _ <- logger.info(...extra info...) _ <- databaseComponent.setup(...) result <- athenaComponent.execute(...) ... } yield ()

Slide 37

Slide 37 text

CirquaでのZIO利用例
 def run(args: List[String]): ZIO[S3Component with AthenaComponent with …, Throwable, BatchResult] = { _ <- logger.info(...) _ <- logger.info(...extra info...) _ <- databaseComponent.setup(...) _ <- athenaComponent.setUp(...) ... } yield () あえてZIOの型を書いてみる(必要ない場合普通は書かない)


Slide 38

Slide 38 text

CirquaでのZIO利用例
 def run(args: List[String]): ZIO[S3Component with AthenaComponent with …, Throwable, BatchResult] = { _ <- logger.info(...) _ <- logger.info(...extra info...) _ <- databaseComponent.setup(...) _ <- athenaComponent.setUp(...) ... } yield () def setUp(...): ZIO[..., …, ...] = for { _ <- s3Component.setupSomething() … }

Slide 39

Slide 39 text

cakeってアンチパターンじゃないの?


Slide 40

Slide 40 text

分割された一つ一つのfor文は
 小さいcakeになるので、昔ながらの cake patternの問題を避けられる
 ZIO cake (module pattern)
 (らしいよ)

Slide 41

Slide 41 text

ZIOとテスト ● Effect(副作用)はだいたいDIのコンポーネントに集中する ● DIを使ってテスト!...あれ?

Slide 42

Slide 42 text

関数型の最大のメリット(の一つ)はtestability! ②
 “I would argue that the whole point of functional programming in general is testing” Free as in Monads - ETE 2017 Daniel Spiewak氏 関数型プログラミング等で特に著名 これ、Algebraic Lawsの話をしている。 (リチャード)

Slide 43

Slide 43 text

Algebraic Lawsの話 ● プログラムが満たすべきルールを、型クラスが満たすべきルールとして定義してい る(はず…間違ってる?)
 ● そもそもデータベース副作用、ファイル副作用に満たすべきAlgebraic Lawつまり代 数的規則などない、数学的に厳密に規則を議論できない
 ● それはtagless finalに代えてZIOを導入しても同じ


Slide 44

Slide 44 text

John De Goes氏の別の発言
 “Tagless-final type classes do not, in general, have algebraic laws. Most have no laws at all. This represents a serious abuse of the construct of a type class ...” Beautiful, Simple, Testable Functional Effects for Scala JOHN A DE GOES (blog) Feb, 2019 John De Goes氏 ZIO作者

Slide 45

Slide 45 text

ZIOとテスト ● イマイチdescriptionとinterpreterの分離によるtestabilityの向上がわからない ● DIを上手く使えばテストが書けるが、それはdescriptionとinterpreterの分離による testability向上ではないのでは? ● 結局この点はについてはtagless-finalも同じだったし、ZIOでも副作用のtestability が向上してるわけではなさそうに見えるのだが… ● というわけでdescriptionとinterpreterの分離の流れに沿うZIOもtestabilityの向上と いう面で見るとメリットが「私には」理解できなかった ● モックを上手く使えばテストが書けるが(同上)

Slide 46

Slide 46 text

ZIOは理解しやすくtestability以外の
 メリットも有る、という話なら分かる


Slide 47

Slide 47 text

ZIOの他のメリット!!


Slide 48

Slide 48 text

省略
 ごめん、まとめる時間がなかった