> 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
