title: RangeReplaceableCollection conformance doesn't require... actually anything
body: <p>According to the documentation:</p>
  <blockquote>
  <p>To add RangeReplaceableCollection conformance to your custom
  collection, add an empty initializer and the replaceSubrange(_:with:)
  method to your custom type.</p>
  </blockquote>
  <p>But in practice it's not required! (except for empty initializer)</p>
  <pre><code>// Just stubs for minimal reproducible code
  struct Category: Hashable {}
  struct Product {}
  
  struct ProductCollection {
      typealias DictionaryType = [Category : [Product]]
  
      // Underlying, private storage
      private var products = DictionaryType()
  
      // Enable our collection to be initialized with a dictionary
      init(products: DictionaryType = DictionaryType()) {
          self.products = products
      }
  }
  
  extension ProductCollection: Collection {
      // Required nested types, that tell Swift what our collection contains
      typealias Index = DictionaryType.Index
      typealias Element = DictionaryType.Element
      
      // The upper and lower bounds of the collection, used in iterations
      var startIndex: Index { return products.startIndex }
      var endIndex: Index { return products.endIndex }
      
      // Required subscript, based on a dictionary index
      subscript(index: Index) -&gt; Iterator.Element {
          get { return products[index] }
      }
      // Method that returns the next index when iterating
      func index(after i: Index) -&gt; Index {
          return products.index(after: i)
      }
  }
  
  extension ProductCollection: ExpressibleByDictionaryLiteral {
      init(dictionaryLiteral elements: (Category, [Product])...) {
          self.init(products: .init(uniqueKeysWithValues: elements))
      }
  }
  
  extension ProductCollection: RangeReplaceableCollection {
      init() {
          products = DictionaryType()
      }
      
  //    func replaceSubrange&lt;C: Collection, R: RangeExpression&gt;(_ subrange: R, with newElements: C)
  //        where Self.Element == C.Element, Self.Index == R.Bound {
  //    }
  }
  </code></pre>
  <p>The code is taken from a great (but not related to the post's topic) <a href="https://www.swiftbysundell.com/articles/creating-custom-collections-in-swift/" rel="nofollow noreferrer">John Sundell article</a>.<br />
  This code compiles even though <code>replaceSubrange</code> function is not provided.</p>
  <p>One more question. Why should I provide an empty initializer explicitly in this situation? I can initialize the struct like <code>ProductCollection()</code> without having that initializer. I can do this for many reasons: 1) <code>products</code> property has initializing value provided 2) main initializer has default value provided 3) there is also a ExpressibleByDictionaryLiteral initializer which can be used to initialize an empty object.<br />
  So why I have to provide one more empty initializer explicitly?</p>
  <p>But please, the first question about <code>replaceSubrange</code> function is more important :)</p>