Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Functional Programming For All - Scala Matsuri 2016

6,689 views

Published on

Functional Programming For All from Scala Matsuri 2016

Published in: Software
  • Be the first to comment

Functional Programming For All - Scala Matsuri 2016

  1. 1. Functional Programming for All Zachary McCoy みんなの関数型プログラミング
  2. 2. About Me • Scala • Iowa, USA • twitter - @ZachAMcCoy • email - zach.mccoy@banno.com
  3. 3. What is Functional Programming? • Programming… with functions • Functions as the main abstraction • Functions as first class values 「関数を用いたプログラミング」 「関数を主な抽象化の道具とする」「第一級値としての関数」
  4. 4. What is Functional Programming? • Controlled side effects • Restricts how we write programs, but not what we can express 「制御された副作用」 「表現の幅は狭めずに、プログラムの書き方を制約する」
  5. 5. Functional Programming • Pure functional core with a layer of side effects on the outside • Side effect - an action in addition to return values • FP - Evaluating expressions • Imperative - programs are composed of statements 中核は純粋関数でその外側の層で副作用が実行される FP は式を評価するのに対し、命令型は命令文から成る
  6. 6. What is a function? • An expression involving one or more variables • Domain and Co-Domain • Unique mapping from D -> CD • Immutability, produces something new 関数とは1つもしくは複数の値に関する式 ドメインとコドメインの一意対応、イミュータブル
  7. 7. Pure Functions • No observable side-effects • Anything that isn’t returning a result • Mutation • I/O • Depends only on arguments or subset of 純粋関数は副作用を持たず、結果は引数にのみ依存する
  8. 8. Pure Functions • Examples • Hashing • Arithmetic 純粋関数例:ハッシュ化、算術演算
  9. 9. Why does purity matter? • Side effects cause order of evaluation to matter • Only have to use local reasoning • Composition and reusability 副作用は実行/評価順の考慮が必要になる、局所化、 合成と再利用性
  10. 10. Why does purity matter? • Separate the computation over the input from how to obtain it • Guarantees Referential Transparency 演算と入力を与える方法を分離、参照透過性を保証
  11. 11. Referential Transparency • An expression can be replaced by its value, provided the expression is pure • A function can only be RT if the inputs are also RT • Referential Transparency enables equational reasoning 参照透過性 (RT): 純粋な式がその値と置き換え可能なこと 関数が参照透過であるためには、入力も透過である必要がある
  12. 12. Substitution Model def greaterThan5(i: Int): Option[Int] = if(i > 5) Some(i) else None def createMessage(): String = greaterThan5(3).map(x => "Was greater than 5") getOrElse "Was less than or equal to 5" def createMessage2(): String = (if(3 > 5) Some(3) else None).map(x => "Was greater than 5") getOrElse "Was less than or equal to 5" def createMessage3(): String = None.map(x => "Was greater than 5") getOrElse "Was less than or equal to 5" 置き換えモデル
  13. 13. Formalize Referential Transparency • An expression, E, is said to be referentially transparent if E can be replaced with its value without changing the behavior of a program • Same effect and output in the end 参照透過性の形式化:式をその値と置き換えることができる プログラムの振る舞いは作用を含め変わってはいけない
  14. 14. Referential Transparency • Mathematics! • (2 * 2 = 4) • Returning errors as values, rather than side effecting 参照透過性は数学! エラーは、副作用ではなく、値で返す
  15. 15. How does this tie together? • Pure functions enable Referential Transparency • RT enables the Substitution model and Equational Reasoning • Pure functions are a huge gain! 純粋関数 参照透過性 置き換えモデル&等式推論 純粋関数 ウマー
  16. 16. Scala and FP • Scala doesn't enforce Referential Transparency • We have to work for it • Limit your set of tools: no vars, pulling from out of scope, exceptions Scala は参照透過性を強制しないため、自前での対応が必要
  17. 17. Scala and FP • Given an impure function of type A => C we can split it into two functions • Pure function of A => B, where B is the description of the result • Impure function of type B => C which is the interpreter of the description 純粋でない関数 A C は、純粋関数 A B と そのインタプリタ B C に分離することが可能
  18. 18. Calculate the oldest 最年長者の計算 case class Person(name: String, age: Int) val p1 = Person("John", 30) val p2 = Person("Jack", 100)
  19. 19. Calculate the oldest これはテストするのが難しい 全部副作用で出力されているので参照透過ではない def calculateOldest(): Unit = { if(p1.age > p2.age) println(s"${p1.name} is oldest") else if(p2.age > p1.age) println(s"${p2.name} is oldest") else println("They are the same age") }
  20. 20. Separation of concerns 関心事の分離 def calculateOldest(p1:Person, p2:Person):Unit = { if(p1.age > p2.age) println(s"${p1.name} is oldest") else if(p2.age > p1.age) println(s"${p2.name} is oldest") else println(s"They are the same age") }
  21. 21. Return values 戻り値を使うことでテストしやすくなった def calculateOldest(p1: Person, p2: Person): Option[Person] = if(p1.age > p2.age) Some(p1) else if(p2.age > p1.age) Some(p2) else None
  22. 22. We can still split more さらに細かく分ける def result(maybePerson:Option[Person]): Unit = maybePerson match { case Some(Person(name, age)) => println(s"${p.name} is oldest") case None => println("They are the same age") }
  23. 23. A pure function core これでコアが純粋関数になった def calculateOldest(p1: Person, p2: Person): Option[Person] def result(maybePerson: Option[Person]): String = maybePerson.map { case Person(name, age) => s"${name} is the oldest" } getOrElse "They are the same age" def combine(p1: Person, p2: Person): Unit = println(result(calculateOldest(p1,p2)))
  24. 24. We’re Hiring! zach.mccoy@banno.com 一緒に働きませんか?

×