[swift-evolution] restricting AnySequence.init

Maxim Moiseev maxim_moiseev at apple.com
Mon Dec 7 14:43:09 CST 2015

Hi all,

Here is the proposal to add more constraints to AnySequence.init in order to implement delegation of method calls to the underlying SequnceType implementation.
https://github.com/moiseev/swift-evolution/blob/restricted-anyseq/proposals/0008-constrained-AnySequence.md <https://github.com/moiseev/swift-evolution/blob/restricted-anyseq/proposals/0008-constrained-AnySequence.md>

(Including full text of the proposal at the bottom for your convenience).

Final goal would be to eventually properly delegate all the calls to `SequenceType` and `CollectionType` methods inside `AnySequence` and `Any${Traversal}Collection`.

Any thoughts and comments are welcome (not creating a PR just yet).


Constraining AnySequence.init

SE-0008 <https://github.com/apple/swift-evolution/blob/master/proposals/0008-constrained-AnySequence.md>
Author(s): Max Moiseev <https://github.com/moiseev>
Status: Review
Review manager: TBD

In order to allow AnySequence delegate calls to the underlying sequence, its initializer should have extra constraints.


At the moment AnyCollection does not delegate calls to SequenceType protocol methods to the underlying base sequence, which results in dynamic downcasts in places where this behavior is needed (see default implementations ofSequenceType.dropFirst or SequenceType.prefix). Besides, and this is even more important, customized implementations of SequenceType methods would be ignored without delegation.

 <https://github.com/moiseev/swift-evolution/blob/restricted-anyseq/proposals/0008-constrained-AnySequence.md#proposed-solution>Proposed solution

See the implementation in this PR <https://github.com/apple/swift/pull/220>.

In order for this kind of delegation to become possible, _SequenceBox needs to be able to 'wrap' not only the base sequence but also it's associated SubSequence. So instead of being declared like this:

internal class _SequenceBox<S : SequenceType>
    : _AnySequenceBox<S.Generator.Element> { ... }
it would become this:

internal class _SequenceBox<
  S : SequenceType
    S.SubSequence : SequenceType,
    S.SubSequence.Generator.Element == S.Generator.Element,
    S.SubSequence.SubSequence == S.SubSequence
> : _AnySequenceBox<S.Generator.Element> { ... }
Which, in it's turn, will lead to AnySequence.init getting a new set of constraints as follows.

Before the change:

public struct AnySequence<Element> : SequenceType {
  public init<
    S: SequenceType
      S.Generator.Element == Element
  >(_ base: S) { ... }
After the change:

public struct AnySequence<Element> : SequenceType {
  public init<
    S: SequenceType
      S.Generator.Element == Element,
      S.SubSequence : SequenceType,
      S.SubSequence.Generator.Element == Element,
      S.SubSequence.SubSequence == S.SubSequence
  >(_ base: S) { ... }
These constraints, in fact, should be applied to SequenceType protocol itself (although, that is not currently possible), as we expect every SequenceType implementation to satisfy them already.

 <https://github.com/moiseev/swift-evolution/blob/restricted-anyseq/proposals/0008-constrained-AnySequence.md#impact-on-existing-code>Impact on existing code

New constraints do not affect any built-in types that conform to SequenceType protocol as they are essentially constructed like this (SubSequence.SubSequence == SubSequence). 3rd party collections, if they use the default SubSequence (i.e. Slice), should also be fine. Those having custom SubSequences may stop conforming to the protocol.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20151207/4a40d8b1/attachment-0001.html>

More information about the swift-evolution mailing list