[swift-evolution] [Review] SE-0094: Add sequence(initial:next:) and sequence(state:next:) to the stdlib

Erica Sadun erica at ericasadun.com
Thu May 19 20:14:50 CDT 2016


Once you start using it, it's really hard to put it down.

-- E, who will not make the obvious "for" joke


> On May 19, 2016, at 7:10 PM, Patrick Smith <pgwsmith at gmail.com> wrote:
> 
> I think that is a little confusing and has potential to be ‘abused’. I think it’s more confusing that a `for(;;)` loop for instance, and that got removed. I think var + AnyIterator is more explicit, and can become the canonical way to do this.
> 
> Hopefully AnyIterator can be optimized to the same performance.
> 
> 
>> On 20 May 2016, at 10:57 AM, Erica Sadun via swift-evolution <swift-evolution at swift.org <mailto:swift-evolution at swift.org>> wrote:
>> 
>>> 
>>> On May 19, 2016, at 6:52 PM, Kevin Ballard via swift-evolution <swift-evolution at swift.org <mailto:swift-evolution at swift.org>> wrote:
>>> 
>>> After having given this some thought, it seems apparent that `sequence(state:next:)` is equivalent to `AnyIterator({ ... })` where the closure captures a single mutable variable. The microbenchmark performance may differ slightly, as the AnyIterator version will allocate a box on the heap to hold the captured variable (assuming it can't get inlined entirely), whereas UnfoldSequence won't. But the functionality is the same.
>>>  
>>> Thus the question: do we want to keep `sequence(state:next:)` or is it too close to AnyIterator in functionality? Arguments in favor of `sequence(state:next:)`:
>>>  
>>> * It's equivalent to unfold and the dual of reduce, so people who've used functional programming languages may expect it to exist.
>>> * It allows you to create ad-hoc stateful sequences without polluting the current scope with a variable that exists solely to be captured.
>>> * If the cost of a small heap allocation is significant for your code, it may be more performant than AnyIterator.
>>>  
>>> Personally, the most important reason here for me is not having to pollute the current closure with a variable. And this could actually be solved another way, by allowing the use of `var` in a capture list, which would let you say something like `AnyGenerator({ [var state=foo] in ... })`.
>>>  
>>> Given all this, at this point I'm actually leaning towards saying`sequence(state:next:)` doesn't pull its own weight and we should just go with `sequence(initial:next:)`.
>>>  
>>> -Kevin Ballard
>> 
>> Adding on, to the best of my understanding the biggest win in the stateful variation is to be able to create a sequence from a starting state without declaring any external variables, as in the perfectly wrong and evil example I showed Kevin:
>> 
>> enum Finger: Int { case Thumb = 1, Pointer, Middle, Ring, Pinky }
>> 
>> extension Finger {
>>     static func members() -> AnySequence<Finger> {
>>         return sequence(Thumb.rawValue, next: {
>>             (inout idx: Int) in
>>             defer { idx += 1 }
>>             return Finger(rawValue: idx)
>>         })
>>     }
>> }
>> 
>> for finger in Finger.members() { print(finger) }
>> 
>> -- E
>> 
>> _______________________________________________
>> swift-evolution mailing list
>> swift-evolution at swift.org <mailto:swift-evolution at swift.org>
>> https://lists.swift.org/mailman/listinfo/swift-evolution <https://lists.swift.org/mailman/listinfo/swift-evolution>

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


More information about the swift-evolution mailing list