[swift-evolution] Proposal: Add scan, takeWhile, dropWhile, and iterate to the stdlib
Seth Friedman
sethfri at gmail.com
Sun Jan 10 23:55:37 CST 2016
To clear my thoughts up a bit, that wasn't an "I'm too lazy to Google what
these functions normally do" comment, but rather an "I believe proposals
should provide as much context as possible about what you'd like to add
along with the benefits of doing so" comment.
On Sun, Jan 10, 2016 at 9:48 PM Seth Friedman <sethfri at gmail.com> wrote:
> I'm not familiar with any of the functions listed and would love to see
> more about them and their usefulness to Swift as part of the proposal.
>
> Thanks!
>
> Seth
> On Sat, Jan 9, 2016 at 5:30 PM Kevin Ballard via swift-evolution <
> swift-evolution at swift.org> wrote:
>
>> Proposal PR submitted as https://github.com/apple/swift-evolution/pull/95
>>
>> -Kevin Ballard
>>
>> On Mon, Dec 28, 2015, at 03:59 PM, Kevin Ballard wrote:
>> > ## Introduction
>> >
>> > Add a few more functional sequence utilities to the standard library.
>> >
>> > ## Motivation
>> >
>> > We have map, filter, and reduce, but we're missing a bunch of useful
>> utilities like scan, iterate, takeWhile, and dropWhile. Interestingly, the
>> stdlib includes an implementation of scan in the doc comment for
>> LazySequenceType, it just doesn't actually provide it as API.
>> >
>> > ## Proposed solution
>> >
>> > We extend SequenceType with 3 new methods scan, takeWhile, and
>> dropWhile. We also add a single global function iterate.
>> >
>> > ## Detailed design
>> >
>> > We add the following extension to SequenceType:
>> >
>> > extension SequenceType {
>> > func scan<T>(initial: T, @noescape combine: (T,
>> Self.Generator.Element) throws -> T) rethrows -> [T]
>> > func dropWhile(@noescape dropElement: (Self.Generator.Element)
>> throws -> Bool) rethrows -> [Self.Generator.Element]
>> > func takeWhile(@noescape takeElement: (Self.Generator.Element)
>> throws -> Bool) rethrows -> [Self.Generator.Element]
>> > }
>> >
>> > These all take functions, so to follow convention they're @noescape and
>> return arrays. We also provide an extension of CollectionType that
>> overrides a couple of these methods:
>> >
>> > extension CollectionType {
>> > func dropWhile(@noescape dropElement: (Self.Generator.Element)
>> throws -> Bool) rethrows -> Self.SubSequence
>> > func takeWhile(@noescape takeElement: (Self.Generator.Element)
>> throws -> Bool) rethrows -> Self.SubSequence
>> > }
>> >
>> > We also provide lazy versions:
>> >
>> > extension LazySequenceType {
>> > func scan<T>(initial: T, combine: (T, Self.Generator.Element) -> T)
>> -> LazyScanSequence<Self.Elements, T>
>> > func dropWhile(dropElement: (Self.Generator.Element) -> Bool) ->
>> LazyDropWhileSequence<Self.Elements>
>> > func takeWhile(takeElement: (Self.Generator.Element) -> Bool) ->
>> LazyTakeWhileSequence<Self.Elements>
>> > }
>> >
>> > extension LazyCollectionType {
>> > func dropWhile(dropElement: (Self.Generator.Element) -> Bool) ->
>> LazyDropWhileCollection<Self.Elements>
>> > func takeWhile(takeElement: (Self.Generator.Element) -> Bool) ->
>> LazyTakeWhileCollection<Self.Elements>
>> > }
>> >
>> > No collection variant of scan is provided because that would require
>> storing the last value in the index itself, which would cause problems if
>> the combine function isn't pure.
>> >
>> > LazyDropWhileCollection would behave similarly to LazyFilterCollection
>> in that it runs the predicate against the elements to drop when accessing
>> startIndex; unlike LazyFilterCollection, because there's nothing else to
>> skip after that point, the index itself can actually be Self.Elements.Index
>> (just like a slice). LazyTakeWhileCollection also runs the predicate
>> against the first element when accessing startIndex, but it does need a
>> unique index type (because endIndex has to be some sentinel value, as it
>> doesn't know where the end is until you reach that point; this index type
>> would therefore only conform to ForwardIndexType).
>> >
>> > And finally, we provide a global function
>> >
>> > func iterate<T>(initial: T, _ f: T -> T) -> IterateSequence<T>
>> >
>> > This function is inherently lazy and yields an infinite list of nested
>> applications of the function, so iterate(x, f) yields a sequence like [x,
>> f(x), f(f(x)), ...].
>> >
>> > -Kevin Ballard
>> _______________________________________________
>> 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/20160111/cbb95736/attachment.html>
More information about the swift-evolution
mailing list