Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Passing function to function arguments

Passing function to function arguments

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

Yoshikuni Kato

December 10, 2017
Tweet

More Decks by Yoshikuni Kato

Other Decks in Programming

Transcript

  1. Passing functions to function
    arguments
    Yoshikuni Kato
    1

    View Slide

  2. 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

    View Slide

  3. 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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  7. 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

    View Slide

  8. 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

    View Slide

  9. 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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  14. 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

    View Slide

  15. 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

    View Slide

  16. 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

    View Slide

  17. 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

    View Slide