Slide 1

Slide 1 text

Passing functions to function arguments Yoshikuni Kato 1

Slide 2

Slide 2 text

Notice This is the English version of "樛හΨ୚හ;ͭͼჁͯ䨗ͣො ΄ϪαЀϕ" which was presented at iOSDC 2017 (2017/09/17) — https://speakerdeck.com/yoching/guan-shu-woyin- shu-tositedu-sushu-kifang-falsepointo 2

Slide 3

Slide 3 text

Who am I? — Yoshikuni Katoҁےᡕኧ懺҂ @yoshikuni_kato — iOS Engineer (3 years) — Yahoo! Japan -> Ohako, inc. — "Radi-Hey" → — Interests: Class Design / FRP / Coordinator Pattern / UI implementation 3

Slide 4

Slide 4 text

Wave of writing functionally — More opportunity to write functionally — FRP (RxSwift / ReactiveSwift) — map / filter / reduce — reducing if and for — more declarative way 4

Slide 5

Slide 5 text

What I talk? — how to write functions as arguments of other functions -> a little change, much declarative way — example: map of array 5

Slide 6

Slide 6 text

How to write #1: Write closures directly let array: [Int] = [1, 2, 3] array.map { number -> Int in return number * 2 } 6

Slide 7

Slide 7 text

Definition of map of array func map(_ transform: (Element) throws -> T) rethrows -> [T] — arguments of map: closure that takes Element and return T — functions are like "named closures" — possible to pass function directly 7

Slide 8

Slide 8 text

How to write #2: Pass function // declare function first func twoTimes(of number: Int) -> Int { return number * 2 } let array: [Int] = [1, 2, 3] array.map(twoTimes) // pass the function 8

Slide 9

Slide 9 text

In case of multiple parameters func someFunc(a: Int, b: Int) -> String { return "a = \(a), b = \(b)" } let array: [Int] = [1, 2, 3] array .map { number -> (a: Int, b: Int) in return (a: number, b: number) // make a tuple } .map(someFunc) 9

Slide 10

Slide 10 text

In case of initializer struct Sample { let number: Int init(number: Int) { self.number = number } } 10

Slide 11

Slide 11 text

How to write #1: Write closure directly let array: [Int] = [1, 2, 3] array.map { number -> Sample in return Sample(number: number) } 11

Slide 12

Slide 12 text

How to write #2: Pass function let array: [Int] = [1, 2, 3] array.map(Sample.init) — initializer(.init) = function which returns the object 12

Slide 13

Slide 13 text

Comparison 1 array.map { number -> Sample in return Sample(number: number) } array.map(Sample.init) 13

Slide 14

Slide 14 text

Comparison 2 array .map { number -> Int in return number * 2 } .map { number -> Sample in return Sample(number: number) } .map { sample -> Foo in return Foo(sample: sample) } array .map(twoTimes) .map(Sample.init) .map(Foo.init) 14

Slide 15

Slide 15 text

Wrap up — a little change, much declarative way — example: convert Model to ViewModel ̴ model.map(ViewModel.init) — extracting logics as methods, as a result — feeling of passing function (different from imperative programming style) 15

Slide 16

Slide 16 text

References — Connecting View Controllers, Swift Talk1 — From Runtime Programming to Functions, Swift Talk2 2 https://talk.objc.io/episodes/S01E19-from-runtime-programming-to-functions 1 https://talk.objc.io/episodes/S01E05-connecting-view-controllers 16

Slide 17

Slide 17 text

One more thing func someFunc(a: Int, b: Int) -> String { return "a: \(a), b: \(b)" } // cannot pass tuples to function itself let parameters = (a: 0, b: 0) someFunc(parameters) // ! (swift3~) // can pass tuples when using map let array: [(Int, Int)] = [(0, 0)] array.map(someFunc) // " (even in swift3) — Please tell me if you know how this is possible 17