Brandon Kase: Grokking Lazy Sequences and Collections

1fa9cb8c7997c8c4d3d251fb5e41f749?s=47 Realm
July 07, 2016

Brandon Kase: Grokking Lazy Sequences and Collections

1fa9cb8c7997c8c4d3d251fb5e41f749?s=128

Realm

July 07, 2016
Tweet

Transcript

  1. 3.
  2. 10.

    HOLDING THINGS let fetchresult = PHAsset.fetchAllAssets/*...*/() var arr = [PHAsset]()

    fetchresult.enumerateAssetsUsingBlock { obj, /*...*/ arr.append(obj as! PHAsset) }
  3. 11.

    HOLDING THINGS let fetchresult = PHAsset.fetchAllAssets/*...*/() var arr = [PHAsset]()

    fetchresult.enumerateAssetsUsingBlock { obj, /*...*/ arr.append(obj as! PHAsset) } // slowwwwww
  4. 13.

    GROUPS OF THINGS A Collection is an Indexable Sequence A

    Sequence is an Iterator maker An Iterator can produce one or more Elements
  5. 15.

    ITERATORPROTOCOL Let's say we want to iterate over the even

    numbers https://i.ytimg.com/vi/A9NfHIIwNN4/maxresdefault.jpg
  6. 16.

    ITERATORPROTOCOL struct Evens: IteratorProtocol { var state: Int = 0

    mutating func next() -> Int? { let curr = state state += 2 return .some(curr) } }
  7. 17.

    ITERATORPROTOCOL let s = Evens() for _ in 1...5 {

    print(s.next()!) // 0, 2, 4, 6, 8 }
  8. 22.

    SEQUENCE extension Sequence where Iterator == Self, Self: IteratorProtocol {

    func makeIterator() -> Iterator { return self } }
  9. 26.

    SEQUENCE must be able to produce an iterator could be

    one-pass or multipass could be finite or infinite
  10. 30.

    COLLECTION struct PhotosMetadata: Collection { /*...*/ var startIndex: Int {

    /*...*/ } var endIndex: Int { /*...*/ } func index(after i: Int) -> Int { /*...*/ } subscript(i: Int) -> PHAsset { /*...*/ } }
  11. 31.

    COLLECTION Why do we need to deal with the index

    crap? struct PhotosMetadata: Collection { /*...*/ var startIndex: Int { /*...*/ } var endIndex: Int { /*...*/ } func index(after i: Int) -> Int { /*...*/ } subscript(i: Int) -> PHAsset { /*...*/ } }
  12. 32.

    COLLECTION RULES has addressable positions (index) must support multipass iteration

    exists a one-to-one mapping of indices to elements No infinite structures! expect O(1) subscript access
  13. 46.

    LAZY GROUPS OF THINGS Transformations computed when the information is

    forced out https://media.giphy.com/media/AyXMnDH4nA7jW/giphy.gif
  14. 53.

    H O W C A N A N O V

    E R R I D E N M E T H O D R E T U R N D I F F E R E N T T Y P E S ?
  15. 55.

    DEFAULT IMPLEMENTATIONS protocol A { } extension A { func

    woo() -> Self { return self } func hi() -> String { return "A" } }
  16. 59.

    DEFAULT IMPLEMENTATIONS // now B subsumes A protocol B: A

    { } extension B { func hi() -> Int { return 0 } }
  17. 66.

    LAZYMAPITERATOR struct LazyMapIterator<Base: Iterator, Element>: IteratorProtocol, Sequence { var _base:

    Base let _transform: (Base.Element) -> Element mutating func next() -> Element? { return _base.next().map(_transform) } }
  18. 68.

    BURRITOS let a = [1,2,3].lazy.map{ $0 + 1 }.filter{ $0

    != 3 } // a: LazyFilterBidirectionalCollection< // LazyMapRandomAccessCollection< // Array<Int>, Int // > // >
  19. 71.

    PHOTOS func prepareData(d: PhotosMetadata) -> ? { return d.lazy .filter{

    $0.isPhoto() } // skip videos .map{ Photo(url: $0.url) } // make photos .map{ PhotoView(photo: $0) } // make view }
  20. 81.

    NEW TORTILLAS // the tortilla sequence struct LazyEveryOtherSequence <S: Sequence>:

    LazySequenceProtocol { var base: S func makeIterator() -> LazyEveryOtherIterator<S.Iterator> { return LazyEveryOtherIterator(base: base.makeIterator()) } }
  21. 82.

    NEW TORTILLAS struct LazyEveryOtherIterator <I: IteratorProtocol>: IteratorProtocol { var base:

    I mutating func next() -> I.Element? { if let _ = base.next() { return base.next() } else { return nil } } }
  22. 87.
  23. 90.

    RECAP Collections hold our photo metadata and photos LazyCollection's map

    transforms our data AnyCollection gives maintainable type signatures
  24. 91.

    RECAP Collections hold our photo metadata and photos LazyCollection's map

    transforms our data AnyCollection gives maintainable type signatures We can create new operators that compose
  25. 95.
  26. 100.

    EAGER GROUPS OF THINGS Eager means operations on the groups

    of things are eager The groups of things themselves can be strict or lazy
  27. 101.
  28. 102.

    UNARY let u: Unary</*...*/> u[""] // 1st element u["x"] //

    2st element u["xx"] // 3st element u["xxx"] // 4st element
  29. 103.

    UNARY Given any input collection addressable via Ints, Create a

    collection addressable via unary numbers!
  30. 108.

    UNARY { var startIndex: String { /*...*/ } var endIndex:

    String { /*...*/ } func index(after i: String) -> String { /*...*/ } subscript(i: String) -> C.Iterator.Element { /*...*/ } }
  31. 114.

    UNARY let u: Unary<Array<Int>> = Unary([1, 2, 3, 4, 5,

    6]) print(u.lazy.map{ x in x + 1 }["xxx"])
  32. 115.

    COLLECTION-INDEX VARIANTS How can you move to the next index?

    Collection (ForwardDirection) Go forward in O(1) BidirectionalCollection Go forward or backward in O(1) RandomAccessCollection Get the difference between two indices in O(1)
  33. 118.

    TYPE ERASURE // one of the inits for AnySequence init<S

    : Sequence where S.Iterator.Element == Element, S.SubSequence : Sequence, S.SubSequence.Iterator.Element == Element, S.SubSequence.SubSequence == S.SubSequence>(_ base: S)