<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 <<a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a>> 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> // Note: I'm simplifying signatures here.</span><br><span></span><br><span> protocol Map: Collection {</span><br><span> associatedtype Key</span><br><span> associatedtype Value</span><br><span> associatedtype Iterator: IteratorProtocol where Iterator.Element == (Key, Value)</span><br><span> </span><br><span> subscript (key: Key) -> Value? { get }</span><br><span> func mapValues<T>(transform: Value -> T) -> [Key: T]</span><br><span> }</span><br></div></blockquote><div><br></div><div>Map should not refine Collection. We could have MapCollection (or KeyValueCollection) that refines both. </div><div><br></div><div><div><font color="#000000"><span style="background-color: rgba(255, 255, 255, 0);">protocol Map {<br> associatedtype Key<br> associatedtype Value<br> subscript (key: Key) -> Value { get }<br>}</span></font></div></div><div><br></div><div><span style="background-color: rgba(255, 255, 255, 0);">protocol MutableMap {<br> associatedtype Key<br> associatedtype Value<br> subscript (key: Key) -> 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. 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). </div><div><br></div><div>Also note that Value *is not* Optional. There are valid maps that don't return Optional. For example, you can implement a Dictionary that takes a default value in its initializer. The function example I just gave is another example. 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. 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> </span><br><span> protocol LazyMap: Map, LazyCollectionProtocol {</span><br><span> subscript (key: Base.Key) -> Base.Value? { get }</span><br><span> func mapValues<T>(transform: Value -> T)(…) -> LazyMappedValuesMap<Base, T></span><br><span> }</span><br><span></span><br><span> extension LazyCollection: LazyMap where Base: Map {</span><br><span> …</span><br><span> }</span><br><span> </span><br><span> struct LazyMapValuesMap<Base: Map, NewValue>: Map {</span><br><span> …</span><br><span> }</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>