> On Jan 5, 2016, at 16:43 , Kevin Ballard <[email protected]> wrote:
> 
> On Tue, Jan 5, 2016, at 03:43 PM, Jordan Rose wrote:
>>  
>>> On Jan 2, 2016, at 23:53, Dave Abrahams via swift-evolution 
>>> <[email protected] <mailto:[email protected]>> wrote:
>>>  
>>>>  
>>>> On Jan 2, 2016, at 11:26 PM, Kevin Ballard via swift-evolution 
>>>> <[email protected] <mailto:[email protected]>> wrote:
>>>>  
>>>> On Sat, Jan 2, 2016, at 11:17 PM, Brent Royal-Gordon wrote:
>>>>>> `buffered` is no more problematic than `lazy` is. In fact, calling 
>>>>>> `buffered` actually doesn't have any side-effects at all (it can avoid 
>>>>>> fetching the first element until you call `first` on the result of 
>>>>>> `buffered`).
>>>>>  
>>>>> If `seq` is a single-pass sequence, then `seq.buffered.first` will 
>>>>> consume an element from `seq`, even though you only accessed two 
>>>>> properties. That's why I call it problematic.
>>>>>  
>>>>> (If calling `buffered` somehow rendered the original sequence 
>>>>> unusable—for instance, if we had some way to express that the 
>>>>> `BufferedSequence` takes unique ownership of its base—this wouldn't 
>>>>> bother me as much.)
>>>>  
>>>> If `sequence` is a single-pass sequence, wrapping it in any other sequence 
>>>> type and then doing anything with that other sequence type makes the 
>>>> original sequence unusable (or rather, you can still use it but the 
>>>> elements yielded from any further access to the original sequence can be 
>>>> completely arbitrary).
>>>>  
>>>> And for the record we already have precedent for the specific case of 
>>>> `seq.prop1.prop2` destructively consuming the original sequence: 
>>>> `seq.lazy.array`.
>>>  
>>> Yes, and there are arguments for dropping “.array” as a property.  The 
>>> convention is that “conversions” (ill-defined, I know) use constructor 
>>> syntax, and we are currently heading towards the elimination of 
>>> "convenience” interfaces that duplicate functionality, so we might end up 
>>> with Array(seq).  
>>>  
>>> All that said, single-pass Sequences are just weird in that they get 
>>> mutated without calling any mutating methods on them; you mutate them by 
>>> calling a mutating method on a separate generator instance.  In other 
>>> words, they fundamentally have reference semantics. There may be some 
>>> better way to address this whole area, but we’ll have to go much deeper 
>>> than merely poking at the question of a `.first` property.
>> 
>>  
>> Should "generate()" be a mutating method on SequenceType, then? And a 
>> non-mutating one on CollectionType, obviously.
>  
> No, that would make SequenceType too hard to use. Specific sequences could 
> still have non-mutating generate() methods, but any kind of generic Sequence 
> wrapper would be forced to use a mutating generate(), and that would make the 
> ergonomics of using them awful. For example, instead of
>  
>     for x in seq.lazy.map(f) { ... }
>  
> you'd have to say
>  
>     var seq2 = seq.lazy.map(f)
>     for x in seq { ... }
>  
> And in the end, it wouldn't really solve anything anyway, because you can 
> still implement single-pass sequences using a non-mutating generate() anyway 
> (either the sequence is a class, or it uses a class or UnsafeMutablePointer 
> internally, or it manipulates global state, e.g. a sequence that reads lines 
> from stdin with readLine()).
>  

That's a good point. I still feel like there's something missing (see also my 
Sequence/Generator/Collection thoughts on the PermutationGenerator thread), but 
we certainly wouldn't want to break simple, common uses of LazySequence or 
AnySequence.

Thanks for steering me in the right direction.
Jordan

_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to