Functional Programming in Swift
-
Upload
kaz-yoshikawa -
Category
Engineering
-
view
2.164 -
download
6
Transcript of Functional Programming in Swift
![Page 1: Functional Programming in Swift](https://reader031.fdocument.pub/reader031/viewer/2022020110/55a204ac1a28abda648b45b0/html5/thumbnails/1.jpg)
Functional Programming in SwiftKaz Yoshikawa
December 2014
![Page 2: Functional Programming in Swift](https://reader031.fdocument.pub/reader031/viewer/2022020110/55a204ac1a28abda648b45b0/html5/thumbnails/2.jpg)
What is Functional Programming?
関数型言語(かんすうがたげんご、functional language)は、関数型プログラミングに向いた特徴を持つプログラミング言語、関数型プログラミング言語である。引数に関数を作用(applicate)させて計算をおこなうことから、作用型言語(applicational language)ともいう。データフロープログラミング言語も関数型言語の一種である。
- Wikipedia
![Page 3: Functional Programming in Swift](https://reader031.fdocument.pub/reader031/viewer/2022020110/55a204ac1a28abda648b45b0/html5/thumbnails/3.jpg)
What is Functional Programming?
In computer science, functional programming is a programming paradigm, a style of building the structure and elements of computer programs, that treats computation as the evaluation of mathematical functions and avoids changing-state and mutable data. It is a declarative programming paradigm, which means programming is done with expressions. In functional code, the output value of a function depends only on the arguments that are input to the function, so calling a function f twice with the same value for an argument x will produce the same result f(x) each time. Eliminating side effects, i.e. changes in state that do not depend on the function inputs, can make it much easier to understand and predict the behavior of a program, which is one of the key motivations for the development of functional programming.
- Wikipedia, en
![Page 4: Functional Programming in Swift](https://reader031.fdocument.pub/reader031/viewer/2022020110/55a204ac1a28abda648b45b0/html5/thumbnails/4.jpg)
What is Functional Programming?
コンピュータサイエンスでは、functional programming は、構造と要素を組み立てるスタイル形式のコンピュータプログラムであり、処理(computation)を数学的な関数の評価として扱い、ステートの変更やデータの変化を避ける。それは、宣言的プログラミングパラダイムであり、プログラミングを表現式として行う。関数のコードでは、関数の出力結果は、その関数への引数が唯一依存し、関数 f を引数 x で2度呼び出した場合でも、それぞれの結果は毎度同じ f(x) であるものとする。副作用の排除、すなわちその関数の入力に依存しないステートの変更、はプログラムの挙動を推測しやすく理解しやすくする事が可能になり、それが、functional programming で開発するモチベーションの鍵の一つである。 - Wikipedia En, - 翻訳:吉川
![Page 5: Functional Programming in Swift](https://reader031.fdocument.pub/reader031/viewer/2022020110/55a204ac1a28abda648b45b0/html5/thumbnails/5.jpg)
with state without state
ステート無 ステート有
ƒ ƒ
x x x x
s
a a b c
![Page 6: Functional Programming in Swift](https://reader031.fdocument.pub/reader031/viewer/2022020110/55a204ac1a28abda648b45b0/html5/thumbnails/6.jpg)
Compositing stateless functions
ƒ
g r
p q s t
ステート有
ƒ
g r
p q s t
ステート無
![Page 7: Functional Programming in Swift](https://reader031.fdocument.pub/reader031/viewer/2022020110/55a204ac1a28abda648b45b0/html5/thumbnails/7.jpg)
Functional Programming• ステートを持たない
• 変数を変化させない ?
• 関数はその手順よりも、どうあるべきか記述する
• Value Oriented Programming*
• 関数はValueとなる
• マルチスレッドでハイパフォーマンスを期待できる* Swift Functional Programming
![Page 8: Functional Programming in Swift](https://reader031.fdocument.pub/reader031/viewer/2022020110/55a204ac1a28abda648b45b0/html5/thumbnails/8.jpg)
Functional-ish
class Counter { var counter = 0 func count(count: Int) { counter += count } } var counter = Counter() counter.count(7) counter.count(10) println(counter.counter) // 17
let list = ["c", "d", "a", "b"] var string = sorted(list) .map({$0.uppercaseString}) .reduce("") {$0 + $1} println(string) // "ABCD"
Object Oriented 的
Functional 的
![Page 9: Functional Programming in Swift](https://reader031.fdocument.pub/reader031/viewer/2022020110/55a204ac1a28abda648b45b0/html5/thumbnails/9.jpg)
Function Chaining• Unix の パイプのように、関数をつなげて、より高度な目的をシンプルに達成可能
• 関数の動作が変数などに依存していると、関数を単純につなげても副作用の恐れがある
• グローバル変数に依存したコードの再利用が難しい構造に似ている
![Page 10: Functional Programming in Swift](https://reader031.fdocument.pub/reader031/viewer/2022020110/55a204ac1a28abda648b45b0/html5/thumbnails/10.jpg)
Function without modifying data collection?
• Array や Dictionary は コピーを使う var list1 = [1, 2, 3] var list2 = list1; // 参照ではなくコピー list2.append(4) var list3 = list2 // 参照ではなくコピー list3.append(5)
println(list1) // 1,2,3 <- 変化なし println(list2) // 1,2,3,4 <- 変化なし println(list3) // 1,2,3,4,5
• 代入文では参照ではなくコピーされる
• でもこれって値の変更じゃん!
![Page 11: Functional Programming in Swift](https://reader031.fdocument.pub/reader031/viewer/2022020110/55a204ac1a28abda648b45b0/html5/thumbnails/11.jpg)
Ideally Immutable, but…
• 関数やメソッド内の結果の影響をその範囲に限定させる
• その関数内で変数を変更しても、その影響をプロパティなどに足跡として残さない
• 変数を変更している最中に別スレッドから同じ関数が呼ばれた場合でもお互いに影響させない
• スレッドが別でもローカル変数は影響を受けない
• @synchronized がいらなくなる?
![Page 12: Functional Programming in Swift](https://reader031.fdocument.pub/reader031/viewer/2022020110/55a204ac1a28abda648b45b0/html5/thumbnails/12.jpg)
High Order Function
![Page 13: Functional Programming in Swift](https://reader031.fdocument.pub/reader031/viewer/2022020110/55a204ac1a28abda648b45b0/html5/thumbnails/13.jpg)
What is High Order Function?
高階関数(こうかいかんすう、英: higher-order function)とは、関数(手続き)を引数にしたり、あるいは関数(手続き)を戻り値とするような関数のことである。 (省略)
高階関数は関数を引数にしたり、あるいは関数を戻り値とするものであり、引数や戻り値の関数もまた高階関数となり得る。高階関数は主に関数型言語やその背景理論であるラムダ計算において多用される。 また、ある関数(手続き)の引数となる関数(手続き)のことを関数引数[1]や手続き引数[2]と呼ぶこともある。
- Wikipedia, Ja
![Page 14: Functional Programming in Swift](https://reader031.fdocument.pub/reader031/viewer/2022020110/55a204ac1a28abda648b45b0/html5/thumbnails/14.jpg)
High Order Function• 関数を引数に与える事ができる
• 関数を戻り値できる
![Page 15: Functional Programming in Swift](https://reader031.fdocument.pub/reader031/viewer/2022020110/55a204ac1a28abda648b45b0/html5/thumbnails/15.jpg)
map
let inputs = [10.0, 20.0, 45.0] var outputs = [Double]() for value in inputs { outputs.append(value * 0.7) } println(outputs) // "[7.0, 14.0, 31.5]"
let inputs = [10.0, 20.0, 45.0] var outputs = map(inputs, { x in x * 0.7}) println(outputs) // "[7.0, 14.0, 31.5]"
[ x1, x2, ... , xn].map(f) -> [f(x1), f(x2), ... , f(xn)]
*1 http://www.weheartswift.com
*1
![Page 16: Functional Programming in Swift](https://reader031.fdocument.pub/reader031/viewer/2022020110/55a204ac1a28abda648b45b0/html5/thumbnails/16.jpg)
{x in x}
let outputs = map(inputs, { x in x * 0.7})
var outputs = [Double]() for x in inputs { outputs.append(x * 0.7) }
![Page 17: Functional Programming in Swift](https://reader031.fdocument.pub/reader031/viewer/2022020110/55a204ac1a28abda648b45b0/html5/thumbnails/17.jpg)
filter• Dictionary の場合
• Array の場合
let inputs = ["Ken":64, "Joe":23, "Jack":32, "Alex":75] let outputs = filter(inputs, { key, value -> Bool in value < 40 }) println(outputs) // "[(Joe, 23), (Jack, 32)]"
let inputs = [64, 23, 32, 75] let outputs = filter(inputs, { value -> Bool in value < 40 }) println(outputs) // "[23, 32]"
![Page 18: Functional Programming in Swift](https://reader031.fdocument.pub/reader031/viewer/2022020110/55a204ac1a28abda648b45b0/html5/thumbnails/18.jpg)
reduce
*1 http://ijoshsmith.com/2014/06/25/understanding-swifts-reduce-method/
*1
![Page 19: Functional Programming in Swift](https://reader031.fdocument.pub/reader031/viewer/2022020110/55a204ac1a28abda648b45b0/html5/thumbnails/19.jpg)
頭の体操• Dictionary の Arrayから、それぞれの key に対する値の和を求めた Dictionary を求めよ。
let outputs = reduce(inputs, [String:Int]()) { (a, b) in var d = a for (k, v) in b { d[k] = (d[k] ?? 0) + v } return d } println(outputs) // [e: 10, w: 7]
e の和 と w の和を求める
たぶん Functional な方法があるにちがいない
let inputs = [["e":5], ["w":4], ["e":3], ["w":3, "e": 2]]
![Page 20: Functional Programming in Swift](https://reader031.fdocument.pub/reader031/viewer/2022020110/55a204ac1a28abda648b45b0/html5/thumbnails/20.jpg)
Currying
![Page 21: Functional Programming in Swift](https://reader031.fdocument.pub/reader031/viewer/2022020110/55a204ac1a28abda648b45b0/html5/thumbnails/21.jpg)
Curryingカリー化 (currying, カリー化された=curried) とは、複数の引数をとる関数を、引数が「もとの関数の最初の引数」で戻り値が「もとの関数の残りの引数を取り結果を返す関数」であるような関数にすること(あるいはその関数のこと)である。 (略) ごく簡単な例として、f(a, b) = c という関数 f があるときに、F(a) = g(ここで、g は g(b) = c となる関数である)という関数 F が、f のカリー化である。
- Wikipedia, ja
![Page 22: Functional Programming in Swift](https://reader031.fdocument.pub/reader031/viewer/2022020110/55a204ac1a28abda648b45b0/html5/thumbnails/22.jpg)
CurryingIn mathematics and computer science, currying is the technique of translating the evaluation of a function that takes multiple arguments (or a tuple of arguments) into evaluating a sequence of functions, each with a single argument (partial application). It was introduced by Moses Schönfinkel and later developed by Haskell Curry.
- Wikipedia, en
![Page 23: Functional Programming in Swift](https://reader031.fdocument.pub/reader031/viewer/2022020110/55a204ac1a28abda648b45b0/html5/thumbnails/23.jpg)
Currying数学とコンピュータサイエンスにおいて、カリー化とは、複数の引数を取る関数の評価を、引数を一つだけ持つ関数(partial application: 部分適用)のシーケンスに変換するテクニックである。
- Wikipedia, en 翻訳: 吉川
![Page 24: Functional Programming in Swift](https://reader031.fdocument.pub/reader031/viewer/2022020110/55a204ac1a28abda648b45b0/html5/thumbnails/24.jpg)
Add• これまでの加算func add(x: Int, y: Int) -> Int { return x + y } add(2, 3) // 5
• Functional ちっくな加算func add(x: Int) -> (Int -> Int) { return { y in return x + y } }
add(2)(3) // 5
let add2 = add(2) add2(3) // 5
![Page 25: Functional Programming in Swift](https://reader031.fdocument.pub/reader031/viewer/2022020110/55a204ac1a28abda648b45b0/html5/thumbnails/25.jpg)
Currying
https://github.com/typelift/swiftz/blob/master/swiftz/Curry.swift
public func curry<A,B,C>(f: (A,B) -> C) -> A -> B -> C { return { a in { b in f(a,b) } } }
public func curry<A,B,C,D>(f: (A,B,C) -> D) -> A -> B -> C -> D { return { a in { b in { c in f(a,b,c) } } } }
public func curry<A,B,C,D,E>(f: (A,B,C,D) -> E) -> A -> B -> C -> D -> E { return { a in { b in { c in { d in f(a,b,c,d) } } } } }
curry(+)(100)(2) // 102curry(+)("Hello, ")("World") // "Hello, World"
![Page 26: Functional Programming in Swift](https://reader031.fdocument.pub/reader031/viewer/2022020110/55a204ac1a28abda648b45b0/html5/thumbnails/26.jpg)
What curry<A,B,C> can do for you?
func add(x: Int, y: Int) -> Int { return x + y }
public func curry<A,B,C>(f: (A,B) -> C) -> A -> B -> C { return { a in { b in f(a,b) } } }
curry(add)(100)(3) // 103
let add100 = curry(add)(100) add100(3) // 103
![Page 27: Functional Programming in Swift](https://reader031.fdocument.pub/reader031/viewer/2022020110/55a204ac1a28abda648b45b0/html5/thumbnails/27.jpg)
What’s gonna happen to Object Oriented Programming?
Are they going to extinct?
![Page 28: Functional Programming in Swift](https://reader031.fdocument.pub/reader031/viewer/2022020110/55a204ac1a28abda648b45b0/html5/thumbnails/28.jpg)
User Interface• UIWindow, NSWindow は class なので参照!
• Foundation ぽい所は Functional
• UIやモデルなどプロパティやステートの更新を必要とする部分は Object Oriented
var window = UIWindow(frame: UIScreen.mainScreen().applicationFrame) window.backgroundColor = UIColor.whiteColor() // do not copy
![Page 29: Functional Programming in Swift](https://reader031.fdocument.pub/reader031/viewer/2022020110/55a204ac1a28abda648b45b0/html5/thumbnails/29.jpg)
Wrap up
![Page 30: Functional Programming in Swift](https://reader031.fdocument.pub/reader031/viewer/2022020110/55a204ac1a28abda648b45b0/html5/thumbnails/30.jpg)
Wrap up• 複雑なコードを完結に書く事が可能
• 再現性が高くバグの少ないコードを書く事が可能
• 学習曲線がきついく、OOPで5分で書けるコードを30分悩んで書く事も
• Objective Oriented Programming も健在
![Page 31: Functional Programming in Swift](https://reader031.fdocument.pub/reader031/viewer/2022020110/55a204ac1a28abda648b45b0/html5/thumbnails/31.jpg)
Thank you