Sent from my iPad
On May 22, 2016, at 1:12 AM, Brent Royal-Gordon via swift-evolution <[email protected]> wrote: >> 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. > > I'm not a member of the core team, but I doubt it's necessary. > > 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: > > // Note: I'm simplifying signatures here. > > protocol Map: Collection { > associatedtype Key > associatedtype Value > associatedtype Iterator: IteratorProtocol where Iterator.Element == > (Key, Value) > > subscript (key: Key) -> Value? { get } > func mapValues<T>(transform: Value -> T) -> [Key: T] > } Map should not refine Collection. We could have MapCollection (or KeyValueCollection) that refines both. protocol Map { associatedtype Key associatedtype Value subscript (key: Key) -> Value { get } } protocol MutableMap { associatedtype Key associatedtype Value subscript (key: Key) -> Value { get set } } 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). 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. > > And implementing the laziness will similarly work best with not only that > feature, but also conditional conformances: > > protocol LazyMap: Map, LazyCollectionProtocol { > subscript (key: Base.Key) -> Base.Value? { get } > func mapValues<T>(transform: Value -> T)(…) -> > LazyMappedValuesMap<Base, T> > } > > extension LazyCollection: LazyMap where Base: Map { > … > } > > struct LazyMapValuesMap<Base: Map, NewValue>: Map { > … > } > > 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.) > > 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`. > > -- > Brent Royal-Gordon > Architechies > > _______________________________________________ > swift-evolution mailing list > [email protected] > https://lists.swift.org/mailman/listinfo/swift-evolution
_______________________________________________ swift-evolution mailing list [email protected] https://lists.swift.org/mailman/listinfo/swift-evolution
