<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><br class=""><div><blockquote type="cite" class=""><div class="">On Jan 11, 2016, at 6:22 PM, Dmitri Gribenko <<a href="mailto:gribozavr@gmail.com" class="">gribozavr@gmail.com</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div dir="ltr" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><div class="gmail_extra"><div class="gmail_quote">On Wed, Jan 6, 2016 at 10:42 AM, plx via swift-evolution<span class="Apple-converted-space"> </span><span dir="ltr" class=""><<a href="mailto:swift-evolution@swift.org" target="_blank" class="">swift-evolution@swift.org</a>></span><span class="Apple-converted-space"> </span>wrote:<br class=""><blockquote class="gmail_quote" style="margin: 0px 0px 0px 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex;"><div style="word-wrap: break-word;" class=""><br class=""><div class=""><span class=""><blockquote type="cite" class=""><div class="">On Jan 6, 2016, at 11:37 AM, Jordan Rose via swift-evolution <<a href="mailto:swift-evolution@swift.org" target="_blank" class="">swift-evolution@swift.org</a>> wrote:</div><br class=""><div class=""><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px;" class=""><div class="">I've bounced this idea off of Dave and Dmitri internally, so might as well put it out publicly:</div><div class=""><br class=""></div><div class="">In Magic DWIM Swift, there would only be two types that you'd ever conform to: a destructive iteration type (today's "Generator"), and a multi-pass indexed type (today's "Collection"). Some <i class="">operations</i> can meaningfully use either one (like forEach or maxElement); these operations go on a general "traversable" type (today's "Sequence").</div><div class=""><br class=""></div><div class="">In this world, both GeneratorType and CollectionType are refinements of SequenceType (i.e. any GeneratorType "is-a" SequenceType), including the necessary default implementations. Maybe we rename some of the protocols in the process. Again, no concrete type would ever conform to SequenceType; it's just something you can use as a generic constraint.</div><div class=""><br class=""></div><div class="">We can't actually do this today because it creates a circularity between SequenceType and GeneratorType that the compiler can't handle. I'm pretty sure it's possible to change the compiler's protocol checking logic to allow this, though.</div><div class=""><br class=""></div><div class="">Anyway, that's that idea. At the very least it helped me clear up my thoughts about Sequence, Collection, and Generator back when I was first learning them.</div><div class=""><br class=""></div><div class="">Jordan</div><div class=""><br class=""></div><div class="">P.S. This idea falls apart if someone comes up with a model (concrete type) for SequenceType that isn't a Collection or Generator. I wasn't able to think of one back when I was originally thinking about this, but of course that doesn't mean there isn't one. (Infinite collections are interesting as discussed on the "cycle" thread, but it's not the sequence/generator distinction that's really meaningful there.)</div></div></div></blockquote><div class=""><br class=""></div></span><div class="">It’s not clear what you mean by a `SequenceType` that isn’t either a `Collection` or a `Generator`, but if you mean a *concrete* sequence that:</div><div class=""><br class=""></div><div class="">- can be re-iterated (thus not a `Generator`)</div><div class="">- has no meaningful index (!) (thus not a `Collection`)</div><div class=""><br class=""></div><div class="">…then I can provide you with examples of such. The (!) is b/c you can of course always use `Int` as an index, in the sense that “the value at index `n` is obtained by iterating `n` steps from the start of the sequence”; I’ll assume this doesn’t “count” as an index for purposes of this discussion.</div></div></div></blockquote><div class=""><br class=""></div><div class="">You can use an opaque data type designed just for that collection, it is a valid design.</div></div></div></div></div></blockquote><div><br class=""></div><div>I suppose you’re right, but wouldn’t the opaque-Int-wrapper-as-Index still only work for a finite sequence with its exact length already-known, so you can provide an `endIndex` in O(1) time?</div><div><br class=""></div><div>I may not be understanding what you mean, here.</div><br class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><div class="gmail_extra"><div class="gmail_quote"><div class=""> </div><blockquote class="gmail_quote" style="margin: 0px 0px 0px 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex;"><div style="word-wrap: break-word;" class=""><div class=""><div class="">Given the above, I will provide two examples.</div><div class=""><br class=""></div><div class="">Here is one that is stable, re-iterable, infinite, and has no “non-trivial" index:</div><div class=""><br class=""></div><div class=""><div class=""> <span class="Apple-converted-space"> </span>// Modest generalization of a seedable PRNG.</div><div class=""> <span class="Apple-converted-space"> </span>// We assume that identically-seeded sources generate</div><div class=""> <span class="Apple-converted-space"> </span>// identical elements (via `randomElement`), in identical order.</div><div class=""> <span class="Apple-converted-space"> </span>protocol RandomElementSourceType {</div><div class=""><br class=""></div><div class=""> <span class="Apple-converted-space"> </span>typealias Element</div><div class=""> <span class="Apple-converted-space"> </span>typealias Seed: Equatable</div><div class=""> <span class="Apple-converted-space"> </span>// ^ `:Equatable` isn't actually necessary, but it's nice</div><div class=""> </div><div class=""> <span class="Apple-converted-space"> </span>init(seed: Seed)</div><div class=""> </div><div class=""> <span class="Apple-converted-space"> </span>mutating func randomElement() -> Element</div><div class=""><br class=""></div><div class=""> <span class="Apple-converted-space"> </span>}</div><div class=""><br class=""></div><div class=""> <span class="Apple-converted-space"> </span>struct RandomElementGenerator<R:RandomElementSourceType> : GeneratorType {</div><div class=""><br class=""></div><div class=""> <span class="Apple-converted-space"> </span>typealias Element = R.Element</div><div class=""> </div><div class=""> <span class="Apple-converted-space"> </span>private var source: R</div><div class=""> </div><div class=""> <span class="Apple-converted-space"> </span>mutating func next() -> Element? {</div><div class=""> <span class="Apple-converted-space"> </span>return source.randomElement() // <- never stops!</div><div class=""> <span class="Apple-converted-space"> </span>}</div><div class=""> </div><div class=""> <span class="Apple-converted-space"> </span>}</div><div class=""><br class=""></div><div class=""> <span class="Apple-converted-space"> </span>struct RandomElementSequence<R:RandomElementSourceType> : SequenceType {</div><div class=""><br class=""></div><div class=""> <span class="Apple-converted-space"> </span>typealias Generator = RandomElementGenerator<R></div><div class=""> </div><div class=""> <span class="Apple-converted-space"> </span>private let seed: R.Seed</div><div class=""> </div><div class=""> <span class="Apple-converted-space"> </span>func generate() -> Generator {</div><div class=""> <span class="Apple-converted-space"> </span>return Generator(source: R(seed: seed))</div><div class=""> <span class="Apple-converted-space"> </span>// ^ as per assumptions, each iteration will be identical b/c</div><div class=""> <span class="Apple-converted-space"> </span>// because each iteration uses the same seed </div><div class=""> <span class="Apple-converted-space"> </span>}</div><div class=""><br class=""></div><div class=""> <span class="Apple-converted-space"> </span>}</div></div></div></div></blockquote><div class=""><br class=""></div><div class=""></div></div><div class="gmail_extra">RandomElementSequence is a forward collection. You can create an index for it that contains the generator state, and computes the next element when the index is advanced. Subscripting the collection with the index would return the value contained in the index.<br class=""></div></div></div></div></blockquote><div><br class=""></div><div>This is a cool trick, but what’s a reasonable choice for `endIndex` here (that isn’t just some “artificial’ truncation of the sequence of random elements)?</div><br class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><div class="gmail_extra"><div class="gmail_extra"><br class=""></div><div class="gmail_extra">Dmitri</div><div class=""><br class=""></div>--<span class="Apple-converted-space"> </span><br class=""><div class="gmail_signature">main(i,j){for(i=2;;i++){for(j=2;j<i;j++){if(!(i%j)){j=0;break;}}if<br class="">(j){printf("%d\n",i);}}} /*Dmitri Gribenko <<a href="mailto:gribozavr@gmail.com" target="_blank" class="">gribozavr@gmail.com</a>>*/</div></div></div></div></blockquote></div><br class=""></body></html>