<html><head><meta http-equiv="content-type" content="text/html; charset=utf-8"></head><body dir="auto"><div><br><br>Sent from my iPad</div><div><br>On May 22, 2016, at 1:12 AM, Brent Royal-Gordon via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a>&gt; wrote:<br><br></div><blockquote type="cite"><div><blockquote type="cite"><span>Obviously if it's required to have a lazy variant for all collection methods, I'd probably pull back this proposal, as it would automatically be rejected by the core team.</span><br></blockquote><span></span><br><span>I'm not a member of the core team, but I doubt it's necessary.</span><br><span></span><br><span>I don't think it makes much sense to wait for a lazy implementation. If there *is* going to be a Map protocol, then the best way to implement it will require an advanced generics feature that's still in the proposal stages:</span><br><span></span><br><span> &nbsp; &nbsp;// Note: I'm simplifying signatures here.</span><br><span></span><br><span> &nbsp; &nbsp;protocol Map: Collection {</span><br><span> &nbsp; &nbsp; &nbsp; &nbsp;associatedtype Key</span><br><span> &nbsp; &nbsp; &nbsp; &nbsp;associatedtype Value</span><br><span> &nbsp; &nbsp; &nbsp; &nbsp;associatedtype Iterator: IteratorProtocol where Iterator.Element == (Key, Value)</span><br><span> &nbsp; &nbsp; &nbsp; &nbsp;</span><br><span> &nbsp; &nbsp; &nbsp; &nbsp;subscript (key: Key) -&gt; Value? { get }</span><br><span> &nbsp; &nbsp; &nbsp; &nbsp;func mapValues&lt;T&gt;(transform: Value -&gt; T) -&gt; [Key: T]</span><br><span> &nbsp; &nbsp;}</span><br></div></blockquote><div><br></div><div>Map should not refine Collection. &nbsp;We could have MapCollection (or KeyValueCollection) that refines both. &nbsp;</div><div><br></div><div><div><font color="#000000"><span style="background-color: rgba(255, 255, 255, 0);">protocol Map {<br>&nbsp; &nbsp; &nbsp; &nbsp;associatedtype Key<br>&nbsp; &nbsp; &nbsp; &nbsp;associatedtype Value<br>&nbsp; &nbsp; &nbsp; &nbsp;subscript (key: Key) -&gt; Value { get }<br>}</span></font></div></div><div><br></div><div><span style="background-color: rgba(255, 255, 255, 0);">protocol MutableMap {<br>&nbsp; &nbsp; &nbsp; &nbsp;associatedtype Key<br>&nbsp; &nbsp; &nbsp; &nbsp;associatedtype Value<br>&nbsp; &nbsp; &nbsp; &nbsp;subscript (key: Key) -&gt; Value { get set }<br>}</span></div><div><br></div><div>There are plenty of times where you need to be able to read from (and sometimes write to) a map without needing to know anything about how the map is implemented. &nbsp;A single argument function should be a valid Map (I know functions cannot conform to protocols, but I argue that they should have this ability eventually, at least protocols that only have subscript requirements).&nbsp;</div><div><br></div><div>Also note that Value *is not* Optional. &nbsp;There are valid maps that don't return Optional. &nbsp;For example, you can implement a Dictionary that takes a default value in its initializer. &nbsp;The function example I just gave is another example. &nbsp;Because Dictionary already defines a Value generic argument and returns 'Value?' From the subscript we will need to either use something clunky like MapValue (which would be 'Value?' for Dictionary) or make a change in Dictionary. &nbsp;But the Map protocol *should not* make the assumption that all maps are partial.</div><br><blockquote type="cite"><div><span></span><br><span>And implementing the laziness will similarly work best with not only that feature, but also conditional conformances:</span><br><span> &nbsp; &nbsp;</span><br><span> &nbsp; &nbsp;protocol LazyMap: Map, LazyCollectionProtocol {</span><br><span> &nbsp; &nbsp; &nbsp; &nbsp;subscript (key: Base.Key) -&gt; Base.Value? { get }</span><br><span> &nbsp; &nbsp; &nbsp; &nbsp;func mapValues&lt;T&gt;(transform: Value -&gt; T)(…) -&gt; LazyMappedValuesMap&lt;Base, T&gt;</span><br><span> &nbsp; &nbsp;}</span><br><span></span><br><span> &nbsp; &nbsp;extension LazyCollection: LazyMap where Base: Map {</span><br><span> &nbsp; &nbsp; &nbsp; &nbsp;…</span><br><span> &nbsp; &nbsp;}</span><br><span> &nbsp; &nbsp;</span><br><span> &nbsp; &nbsp;struct LazyMapValuesMap&lt;Base: Map, NewValue&gt;: Map {</span><br><span> &nbsp; &nbsp; &nbsp; &nbsp;…</span><br><span> &nbsp; &nbsp;}</span><br><span></span><br><span>If we *don't* wait, on the other hand, we're going to end up in manual-specification and GYB hell. (And even then, I believe conditional conformances are not enough to force all LazyCollectionProtocol conformers to support Map if they have a Map base. You'd need conditional *conformance requirements*, which are *not* planned because it's not safe to add a requirement to a protocol.)</span><br><span></span><br><span>I just don't think laziness is so crucial that we should stop the presses until we have it. `mapValues` carries water all by itself, even without a matching `lazy.mapValues`.</span><br><span></span><br><span>-- </span><br><span>Brent Royal-Gordon</span><br><span>Architechies</span><br><span></span><br><span>_______________________________________________</span><br><span>swift-evolution mailing list</span><br><span><a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a></span><br><span><a href="https://lists.swift.org/mailman/listinfo/swift-evolution">https://lists.swift.org/mailman/listinfo/swift-evolution</a></span><br></div></blockquote></body></html>