[swift-evolution] Bike-shedding alternate collections API

Howard Lovatt howard.lovatt at gmail.com
Thu Mar 24 17:06:18 CDT 2016


Detailed comments about iterator inline below.

Big picture is:

Separating lazy collections from eager collection with a view to a future world with lazy parallel collections.
Returning AnyXxx rather than a specific type to both keep types short and to be more flexible.
Removing constraints on Index, useful for linked lists etc.
Changing the way Range works to that it plays nicer with a larger range of types; range[index] = start + index * stride
Flattening the hierarchy, to allow a mix and match approach to features for more flexibility.

Saying problem to be solved is too strong. There is no real problem with the current collections. They work just fine. However I think they could be finessed. Much like many of the things discussed on swift-eveolution :(

> On 25 Mar 2016, at 8:28 AM, Dave Abrahams via swift-evolution <swift-evolution at swift.org> wrote:
> 
> 
> on Thu Mar 24 2016, Howard Lovatt <swift-evolution at swift.org> wrote:
> 
>> _______________________________________________ swift-evolution mailing list swift-evolution at swift.org https://lists.swift.org/mailman/listinfo/
>> swift-evolution
>> 
>> Bike-shedding alternate collections API - cut down to keep them short enough to post.
>> 
>> They differ from the current collections API and the new proposed collections API in that:
>> 
>> 1. They use the existing external iterator, 
> 
> You mean index.

For the proposed new collections you would write:

    var iterator = array.iterator
    let element = array.next(&iterator)

You can’t type erase the returned iterator because it must be called on the original array and therefore must be of the type that that specific array’s next method accepts, not an arbitrary AnyIterator type. These proposed iterators are a cross between an internal and external iterator.

The current and the iterator I used are classic internal iterators and therefore can be type erased because they encapsulate the collection being iterated and the iteration state.

> 
>>    `iterator.next()`, rather
>>    than the proposed style, `iterator.next(&i)`, because the new style
>>    ties the iterator to a particular collection type and therefore
>>    cannot be type erased.
> 
> The new style does not prevent type erasure.  See
> https://github.com/apple/swift/blob/swift-3-indexing-model/stdlib/public/core/ExistentialCollection.swift.gyb
> for an example.

This is for the current behaviour which I used. Is this the correct reference?

> 
>>    Type erasure is required to keep return types generic, e.g. rather than
>>    map returning an Array it returns an `AnyNextorable<Element>` (see point 5 below).
>> 2. The protocols are not, in general, heirarchical; instead they are small building blocks at the top level that can be fitted together.
>> 3. Protocols are split when a good default implementation cannot be provided, e.g. CountableCollection is seperate because the default of iterating and
>>    counting the elements is not a good implimentation of count.
>> 4. Hierarchies are used for convenience, e.g. ArrayCollection is a convenience protocol that extends base protocols.
>> 5. The protocol member's return generic implementations of protocols, e.g. where you might return an Array instead you return an `AnyNextorable<Element>`.
>>    This sidesteps issues with associated types and generics and prevents large type signatures. The downside is that you have comitted to a particular
>>    interface and therefore lost covariance. When generics are completed hopefully these return types can be replaced with `Any<... where ...>`, e.g. `Any
>>    <Nextorable where Element == Element>`
>> 6. LazyNextable is split out seperately so that the semantics of lazy are articulated in the type system. The design of LazyNextable is also compatible
>>    with adding ParallelLazyNextable in the future.
>> 7. The naming of the protocols is one of:
>>     1. Xxxable because it is a main behavioural protocol and its main member is xxx, e.g. Nextorable has a main property nextor.
>>     2. If in the rare case that a protocol extends another protocol then the new property is prepended, e.g. MutableSubstriptable extends Substriptable
>>        and the main method added is mutable subscripting.
>>     3. If they don't have a main member then they are named after what they are used for, e.g. ArrayCollection defines the members of Array like
>>        collections. Note name format of XxxCollection.
>>     4. AnyXxxx is a type erased implimentation of Xxx, e.g. AnyLazyNextable is an erased LazyNextable.
>>     5. Xxxee and xxxee is used for the subject of an action, e.g. Rangee is a collection of methods that a type must impliment to be used in a Range.
>> 8. Range has an Int index of 0 to count - 1 and a value of start + index * stride, where start and stride are of type Rangee. Int and Double via extension
>>    are made Rangees.
>> 9. Index, used in Subscriptables, can be any type.
> 
> Let's cut to the chase: what problem are you trying to solve, and how
> does your proposal address that problem?
> 
> -- 
> Dave
> 
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160325/0c1dd525/attachment.html>


More information about the swift-evolution mailing list