<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 Dec 30, 2015, at 3:39 PM, Kevin Ballard via swift-evolution <<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>> wrote:</div><br class="Apple-interchange-newline"><div class="">
<title class=""></title>
<div class=""><div class="">Refactoring like that can always be done later; introducing infinite sequences now shouldn't make it any harder to refactor the protocols. If anything, it will provide more practical experience with how infinite sequences interact with the current protocol hierarchy that would help guide the design of any refactoring (or, perhaps more importantly, help determine if such a refactoring is worthwhile).<br class=""></div>
<div class=""> </div>
<div class="">A big concern I have with refactoring like that is you'd rarely ever be able to actually bound an algorithm on FiniteSequenceType, because there will always be ways of constructing sequences that the compiler can't tell if it's infinite. Trivial example is `<span class="font" style="font-family: menlo, consolas, "courier new", monospace, sans-serif;">ary.cycle.takeWhile(pred)</span>`. This is infinite if `<span class="font" style="font-family: menlo, consolas, "courier new", monospace, sans-serif;">pred(elt)</span>` is true for every element of `<span class="font" style="font-family: menlo, consolas, "courier new", monospace, sans-serif;">ary</span>` and finite otherwise. But there's tons of other ways of creating such indeterminate sequences. Bounding algorithms (such as `<span class="font" style="font-family: menlo, consolas, "courier new", monospace, sans-serif;">map(..) -> [T]</span>` or `<span class="font" style="font-family: menlo, consolas, "courier new", monospace, sans-serif;">reduce()</span>`) on finite sequences only would be rather limiting, as users who know their sequence must be finite but can't prove it to the compiler would be unable to use methods that are in fact perfectly safe.<br class=""></div></div></div></blockquote><div><br class=""></div><div>If you will accept that I would prefer the standard library types to interpret the standard library protocols as having already made such a binding — as, indeed, the type signatures necessarily imply — the rest of my objection should be comprehensible.</div><div><br class=""></div><div>I don’t find the repeated points about what can happen due to user error to be interesting.</div><div><br class=""></div><blockquote type="cite" class=""><div class=""><div class=""><br class=""></div>
<div class="">What you could do with such a refactoring is optimize certain algorithms if they use a more precise sequence type, but I'm not actually sure what sort of optimizations you can make with your proposed protocol hierarchy. In fact, the only real optimizations that come to mind are optimizing when you know you're working with a CycleSequence, because for various algorithms you really only have to iterate the underlying elements once (e.g. assuming a pure predicate, CycleSequence can implement contains() safely, although we don't actually have pure in the language right now so that's not necessarily a safe assumption; also, contains() isn't a protocol method, just an extension method, so we can't actually do that anyway).<br class=""></div></div></blockquote><div><br class=""></div><div>I already gave the example of a product sequence. There’s a simple implementation that is correct when both input sequences are finite-and-stable, but not necessarily if otherwise; the proposed refactoring would statically provides enough information to allow one to choose the minimally-*pessimal* implementation that is still correct for such inputs. </div><div><br class=""></div><div>How much correctness matters is, of course, essentially subjective.</div><div><br class=""></div><blockquote type="cite" class=""><div class=""><div class=""><div class=""> </div>
<div class="">On that note, core language team, anyone know offhand why SequenceType has a bunch of extension methods that aren't part of the protocol? For example, <span class="font" style="font-family: menlo, consolas, "courier new", monospace, sans-serif;">contains(_ predicate:)</span>. The only real reason I can think of is to shrink the protocol witness table, but surely that's not particularly meaningful. I warrant that <span class="font" style="font-family: menlo, consolas, "courier new", monospace, sans-serif;">contains(_ predicate:)</span> doesn't really have any reason to be overridden by anything except sequences that knowingly repeat elements (e.g. CycleSequence and Repeat), and even that's only if you assume the predicate is pure, but there's some other methods that make sense to override on some sequences (like <span class="font" style="font-family: menlo, consolas, "courier new", monospace, sans-serif;">minElement(_ isOrderedBefore:)</span> for any sequence that has a defined ordering).<br class=""></div></div></div></blockquote><div><br class=""></div><div>I am not sure how, precisely, you would propose to override the closure-taking variant of `minElement` to take advantage of an intrinsic ordering, but I’d be curious to see it.</div><div><br class=""></div><div>I’d hope that the non-closure-accepting variants would be made overridable once the type system supports it.</div><br class=""><blockquote type="cite" class=""><div class=""><div class="">
<div class=""> </div>
<div class="">-Kevin Ballard</div>
<div class=""> </div>
<div class="">On Wed, Dec 30, 2015, at 11:01 AM, plx via swift-evolution wrote:<br class=""></div>
<blockquote type="cite" class=""><div class=""> </div>
<div class=""><blockquote type="cite" class=""><div class="">On Dec 29, 2015, at 6:38 PM, Dave Abrahams <<a href="mailto:dabrahams@apple.com" class="">dabrahams@apple.com</a>> wrote:<br class=""></div>
<div class=""> </div>
<div class=""><div style="word-wrap:break-word;-webkit-line-break:after-white-space;" class=""><div class=""> </div>
<div class=""><blockquote type="cite" class=""><div class="">On Dec 29, 2015, at 3:39 PM, plx via swift-evolution <<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>> wrote:<br class=""></div>
<div class=""> </div>
<div class=""><div style="font-family:AvenirNext-Medium;font-size:15px;font-style: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=""><blockquote type="cite" class=""><div class=""><div class=""> </div>
<div class="">On Dec 29, 2015, at 1:17 PM, Kevin Ballard via swift-evolution <<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>> wrote:<br class=""></div>
</div>
<div class=""> </div>
<div class=""><div class=""><span class="font" style="font-family:Helvetica"><span class="size" style="font-size:12px">On Tue, Dec 29, 2015, at 08:14 AM, plx via swift-evolution wrote:</span></span><br class=""></div>
<blockquote style="font-family:Helvetica;font-size:12px;font-style: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;" type="cite" class=""><div class="">Personally I’d say this should be a -1 for standard-library inclusion.<br class=""></div>
<div class=""> </div>
<div class="">Swift’s not really built to handle infinite sequences right now; until they are handed better by the standard library convenience methods for creating them shouldn’t be in the standard library.<br class=""></div>
</blockquote><div class=""> </div>
<div class=""><span class="font" style="font-family:Helvetica"><span class="size" style="font-size:12px">As far as I can tell, the only way in which it's "not really built" to handle this is that there are multiple constructs that attempt to eagerly consume an entire sequence, and using these with an infinite sequence would end up looping forever. But I don't consider that to be a particularly serious problem. You could "fix" it by refactoring SequenceType into two protocols, SequenceType (for possibly-infinite sequences) and FiniteSequenceType (for known-finite sequences) and then going over the entire standard library and updating various spots to use FiniteSequenceType, except this would be very limiting (sequences that are not known if they're infinite to the compiler could still be valid for various eager algorithms if the programmer knows it will be finite in practice).</span></span><br class=""></div>
</div>
</blockquote><div class=""> </div>
<div class="">Indeed, on my wishlist I would like to see the standard protocols refactored to something more like this:<br class=""></div>
<div class=""> </div>
<div class="">SequenceType // can be iterated<br class=""></div>
<div class="">FiniteSequenceType : SequenceType, // of finite length<br class=""></div>
<div class="">StableSequenceType : SequenceType, // can be re-iterated identically<br class=""></div>
<div class="">CollectionType : StableSequenceType, FiniteSequenceType, (etc.) // otherwise as it is now<br class=""></div>
</div>
</div>
</blockquote><div class=""> </div>
<div class="">This is interesting. A few concerns:<br class=""></div>
<div class=""> </div>
<div class="">First, we have tried not to create any distinct protocols with identical syntactic requirements, because we think it makes the world clearer; we think people are more likely to assign incorrect protocols when all the operations they want are available, but don’t have the right semantics. That isn’t to say we shouldn’t start doing it, but it would be a break from the past.<br class=""></div>
<div class=""> </div>
<div class="">Higher protocol granularity has a high comprehensibility cost. Distinguishing protocols based on semantic requirements alone may make the library harder to understand. I’ve heard some people’s heads have exploded from simply encountering CollectionType. <br class=""></div>
<div class=""> </div>
<div class="">Next, it’s a principle of generic programming that every protocol should be justified by both algorithms that exploit its requirements (e.g. extension methods) and some real-world models that can’t reasonably also conform to a more-refined protocol. For example, we have a ForwardIndexType because a singly-linked list has multipass forward traversal and can’t do bidirectional traversal. In order to evaluate any proposal for new protocols, we’d need to see all of these things.<br class=""></div>
</div>
</div>
</div>
</blockquote><div class=""> </div>
<div class="">Speaking frankly, I’d say that there are few benefits to a refactoring along the lines sketched above until/unless you want to have solid support for things like a product-sequence or product-collection; you would gain *significant* advantages from such a refactored hierarchy in such scenarios, but I can’t think of any meaningful improvement the refactoring would offer in the essentially-linear case. (Note that this is distinct from examples of concrete models that are naturally e.g. finite-but-not-stable and vice-versa; they exist, but the rest is already long enough as it is).<br class=""></div>
<div class=""> </div>
<div class="">A full example is beyond my time-budget here, but I can give the flavor of where it makes a difference somewhat quickly.<br class=""></div>
<div class=""> </div>
<div class="">Consider a hypothetical `ProductSequence2<A:SequenceType,B:SequenceType>` that enumerates the cartesian product of two sequences (in an unspecified order); the naive implementation has problems with non-stable sequences and with infinite-sequences, but I’ll only discuss the infinite case b/c it’s more relevant here.<br class=""></div>
<div class=""> </div>
<div class="">When either—or both—of the sequences are infinite, the order-of-iteration has actual observable consequences; as a concrete example, if you want this to work out:<br class=""></div>
<div class=""> </div>
<div class=""><span style="white-space:pre;" class=""></span>ProductSequence2([1,2].cycle,[1,2].cycle).contains((2,2)) == true<br class=""></div>
<div class=""> </div>
<div class="">…then we have this:<br class=""></div>
<div class=""><div class=""> </div>
<div class="">- if `a` is finite and `b` is not, you want to iterate like (a0,b0), (a1,b0), (a2, b0) … , (a0, b1), (a1, b1), …, etc<br class=""></div>
<div class="">- if `b` is finite and `a` is not, you want to iterate like (a0,b0), (a0,b1), (a0, b2) … , (a1, b0), (a1, b1), …, etc <br class=""></div>
<div class="">- if neither `a` nor `b` is finite, you want to iterate like (a0, b0), (a1,b0), (a0,b1), (a2, b0), (a1, b1), (a0, b2), … etc<br class=""></div>
<div class=""> </div>
<div class="">…as with those orderings you *will* eventually reach each pair in the product (which seems strictly superior to an iteration order which will leave many members of the product forever un-visited).<br class=""></div>
<div class=""> </div>
<div class="">Importantly, the third ordering is inefficient in the general case, and thus isn’t a suitable default; you’d only want it in places where you’re *intentionally* using infinite series.<br class=""></div>
<div class=""> </div>
<div class="">This is a concrete example of the sort of thing that leaves me preferring that the standard library *not* contain infinite sequences at this time: such sequences *highly* benefit from special handling, but there’s no good way at this time to generically provide such handling in a general context within the bounds of the current language and standard library .<br class=""></div>
<div class=""> </div>
<div class="">If there’s a realistic chance of such a refactoring being accepted if sufficiently-well-proposed I can prepare something, but I’m admittedly skeptical given the likely magnitude of the associated changes. In particular, the API on types like `ForwardIndexType` is rather unfortunate for things like a hypothetical product-collection scenario; since such products are among the stronger motivating uses, this means it’s a protocol refactoring + a lot of API changes to the existing standard library, and probably making things clunkier in the common / linear cases.<br class=""></div>
</div>
<div class=""> </div>
<blockquote type="cite" class=""><div class=""><div style="word-wrap:break-word;-webkit-line-break:after-white-space;" class=""><div class=""><div class=""> </div>
</div>
<div class=""><blockquote type="cite" class=""><div class=""><div style="font-family:AvenirNext-Medium;font-size:15px;font-style: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="">…but can understand the wish to not overly-complicate the basic protocol hierarchy (and also to avoid baking-in nice-to-have, but impossible-to-really-enforce semantic requirements; I’d trust the standard library to use them properly, but not typical 3rd party code, somewhat defeating the purpose).<br class=""></div>
</div>
</div>
</blockquote><div class=""> </div>
<div class="">Well, I guess I should have read ahead and most of my lecture above was needless! I’m posting it anyway because I think it spells out some important principles we’ll need to refer to later.<br class=""></div>
</div>
<div class=""><div class=""> </div>
<blockquote type="cite" class=""><div class=""><div style="font-family:AvenirNext-Medium;font-size:15px;font-style: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="">Everything else is a difference of outlook; we agree on the facts and differ in interpretation.<br class=""></div>
<div class=""> </div>
<div class="">I consider concrete types that adopt a protocol only to simply call `fatalError` for most of the protocol methods to be pathological — often useful, but still pathological — and thus far the standard library doesn’t contain any such pathological types (to my knowledge).<br class=""></div>
<div class=""> </div>
<div class="">`cycle` is useful but not useful enough to be the standard library’s first “pathological” type, so it’s still a -1 as proposed.<br class=""></div>
<div class=""> </div>
<div class="">This is nothing specific to `cycle` and my opinion here could change were the language or the standard library to evolve in various ways.<br class=""></div>
<blockquote type="cite" class=""><div class=""><div class=""> </div>
<blockquote style="font-family:Helvetica;font-size:12px;font-style: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;" type="cite" class="">You’d also want to call `fatalError` for at least `reduce`, `reverse`, `sort`, `split`(?), `flatMap`, `dropLast`, `suffix`, and `forEach`.<br class=""></blockquote><div class=""> </div>
<div class=""><span class="font" style="font-family:Helvetica"><span class="size" style="font-size:12px">You can only do it for the ones defined in the protocol, not ones defined in extensions. This means map, filter, forEach, and suffix.</span></span><br class=""></div>
</div>
</blockquote><blockquote type="cite" class=""><div class=""><div class=""> </div>
<div class=""><span class="font" style="font-family:Helvetica"><span class="size" style="font-size:12px">split is actually perfectly implementable for a CycleSequence, although it does need a custom implementation. split is bounded by at most Int.max splits, which means it is guaranteed to terminate even for an infinite sequence (although the final subsequence does need to be infinite[1]). Even if there are no separators in the cycle, it can just return the cycle itself.</span></span><br class=""></div>
<div class=""> </div>
<div class=""><span class="font" style="font-family:Helvetica"><span class="size" style="font-size:12px">[1] Interestingly, the current implementation actually dumps the remainder into an Array and returns that (wrapped in AnySequence), which is curious because it would be perfectly legal for it to just wrap the generator up in AnySequence and return that instead. I'm tempted to submit a PR to change that now, as it just seems like unnecessary work to use an array.</span></span><br class=""></div>
<div class=""> </div>
<blockquote style="font-family:Helvetica;font-size:12px;font-style: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;" type="cite" class="">`startsWith` and `elementsEqual` and `lexicographicComparison` are all broken if you call them like e.g. `self.startsWith(self)`.<br class=""></blockquote><div class=""> </div>
<div class=""><span class="font" style="font-family:Helvetica"><span class="size" style="font-size:12px">That's true, but what do you really expect when you're calling them with two infinite sequences? It's not so much that they're broken as it is that you're creating an infinite loop without any way to break out. And FWIW, lexicographicalCompare is actually something you might want to explicitly support on infinite sequences if you know your sequences aren't equal and want to find out which one is less than the other.</span></span><br class=""></div>
<div class=""> </div>
<div class=""><span class="font" style="font-family:Helvetica"><span class="size" style="font-size:12px">There are plenty of ways to shoot yourself in the foot. I don't think infinite sequences are really the big problem you're making them out to be.</span></span><br class=""></div>
</div>
</blockquote><blockquote type="cite" class=""><div class=""><div class=""> </div>
<blockquote style="font-family:Helvetica;font-size:12px;font-style: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;" type="cite" class="">You can conceivably implement a non-crashing `contains`, `minElement` and `maxElement` on `CycleSequence` by calling through to the wrapped collection, but that’ll seemingly evaporate as soon as your `CycleSequence` winds up hidden inside an `AnySequence`.<br class=""></blockquote><div class=""> </div>
<div class=""><span class="font" style="font-family:Helvetica"><span class="size" style="font-size:12px">You can't override those anyway in a generic context, because they're not members of the protocol, they're just extensions. You could implement them such that your implementation is called when working on the concrete CycleSequence type, but I'm not sure if that's a great idea to do that when the actual behavior differs from calling it generically on SequenceType (well, triggering a fatalError() instead of an infinite loop is fine because they're both Bottom, but returning a valid result in one context and looping infinitely in the other seems bad).</span></span><br class=""></div>
<div class=""> </div>
<div class=""><span class="font" style="font-family:Helvetica"><span class="size" style="font-size:12px">Of course, these methods could actually be moved into the protocol itself, which would let us override them. I'm not entirely sure why they aren't in the protocol to begin with, I guess because there's not much need for overriding these outside of infinite sequences (well, finite sorted sequences could provide an optimized min/maxElement, and an optimized version of contains(_: Self.Generator.Element), but maybe there's tradeoffs to doing this, e.g. maybe there's some reason why having a large protocol witness table is a bad idea).</span></span><br class=""></div>
</div>
</blockquote><div class=""> </div>
<div class="">I don’t think `contains` or `minElement/maxElement` *can* be part of the protocol (in the sense of overridable) at this time (they require `Element` satisfy certain type constraints), but they certainly should be if the type system someday would support that.<br class=""></div>
<div class=""> </div>
<blockquote type="cite" class=""><div class=""><div class=""> </div>
<blockquote style="font-family:Helvetica;font-size:12px;font-style: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;" type="cite" class="">Which illustrates why this is a -1 for me; there's nothing wrong with the functionality in isolation and there’s nothing wrong with infinite sequences, but the standard library should play well with itself, and this wouldn’t play well with the rest of the standard library.<br class=""></blockquote><div class=""> </div>
<div class=""><span class="font" style="font-family:Helvetica"><span class="size" style="font-size:12px">Ultimately, there's not much difference between an infinite sequence and a sequence of Int.max elements. The latter is finite, but it's so massive (especially on 64-bit) that any kind of eager processing is going to hit the same problems as an infinite sequence. Every problem you describe will be a problem with the simple sequence `(0..<Int.max)` as well.</span></span><br class=""></div>
</div>
</blockquote><blockquote type="cite" class=""><div class=""><div class=""> </div>
<div class=""><span class="font" style="font-family:Helvetica"><span class="size" style="font-size:12px">-Kevin Ballard</span></span><br class=""></div>
<div class=""> </div>
<blockquote style="font-family:Helvetica;font-size:12px;font-style: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;" type="cite" class=""><div class="">That opinion could change as the language changes or the standard library evolves.<br class=""></div>
<div class=""> </div>
<blockquote type="cite" class=""><div class="">On Dec 28, 2015, at 1:20 AM, Kevin Ballard via swift-evolution <<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>> wrote:<br class=""></div>
<div class=""> </div>
<div class="">## Introduction<br class=""></div>
<div class=""> </div>
<div class="">Add a new property `cycle` to CollectionType that returns an infinite SequenceType that yields the elements of the collection in a loop.<br class=""></div>
<div class=""> </div>
<div class="">## Motivation<br class=""></div>
<div class=""> </div>
<div class="">It's sometimes useful to be able to have an infinite sequence. For example, `CollectionOfOne(x).cycle` could be used to have an infinite sequence of a single element (similar to Repeat but without a count). A common use for infinite sequences is zipping with a finite sequence. As far as I'm aware, the stdlib does not currently provide any way to create such an infinite sequence.<br class=""></div>
<div class=""> </div>
<div class="">## Proposed solution<br class=""></div>
<div class=""> </div>
<div class="">Extend CollectionType with a new property `cycle` that yields a type that conforms to SequenceType. This sequence yields each element of the collection in an infinite loop.<br class=""></div>
<div class=""> </div>
<div class="">## Detailed design<br class=""></div>
<div class=""> </div>
<div class="">2 new types would be added:<br class=""></div>
<div class=""> </div>
<div class="">struct CycleSequence<Base : CollectionType> : LazySequenceType { ... }<br class=""></div>
<div class="">struct CycleGenerator<Base : CollectionType> : GeneratorType { ... }<br class=""></div>
<div class=""> </div>
<div class="">CollectionType would be extended with a property:<br class=""></div>
<div class=""> </div>
<div class="">extension CollectionType {<br class=""></div>
<div class=""> public var cycle: CycleSequence<Self> { get }<br class=""></div>
<div class="">}<br class=""></div>
<div class=""> </div>
<div class="">This is an extension of CollectionType instead of SequenceType because it requires a multi-pass sequence (and SequenceType does not provide that guarantee). The returned type conforms to SequenceType instead of CollectionType because there is no possible `endIndex` that satisfies the requirement of being reachable from `startIndex` by zero or more applications of `successor()`.<br class=""></div>
<div class=""> </div>
<div class="">Because the default eager versions of map and filter will execute forever on an infinite sequence, CycleSequence conforms to LazySequenceType instead of SequenceType in order to provide lazy versions of those functions. Additionally, it will provide implementations of the eager versions that simply trigger a fatalError(), as the alternative is an infinite loop that consumes more and more memory.<br class=""></div>
<div class=""> </div>
<div class="">## Impact on existing code<br class=""></div>
<div class=""> </div>
<div class="">None<br class=""></div>
<div class=""> </div>
<div class="">-Kevin Ballard<br class=""></div>
<div class="">_______________________________________________<br class=""></div>
<div class="">swift-evolution mailing list<br class=""></div>
<div class=""><a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a><br class=""></div>
<div class=""><a href="https://lists.swift.org/mailman/listinfo/swift-evolution" class="">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br class=""></div>
</blockquote><div class=""> </div>
<div class="">_______________________________________________<br class=""></div>
<div class="">swift-evolution mailing list<br class=""></div>
<div class=""><a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a><br class=""></div>
<div class=""><a href="https://lists.swift.org/mailman/listinfo/swift-evolution" class="">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br class=""></div>
</blockquote><div class=""><span class="font" style="font-family:Helvetica"><span class="size" style="font-size:12px">_______________________________________________</span></span><br class=""></div>
<div class=""><span class="font" style="font-family:Helvetica"><span class="size" style="font-size:12px">swift-evolution mailing list</span></span><br class=""></div>
<div class=""><a style="font-family:Helvetica;font-size:12px;font-style: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;" href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a><br class=""></div>
<div class=""><a style="font-family:Helvetica;font-size:12px;font-style: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;" href="https://lists.swift.org/mailman/listinfo/swift-evolution" class="">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br class=""></div>
</div>
</blockquote></div>
<div class=""> </div>
<div class=""><img style="font-family:AvenirNext-Medium;font-size:15px;font-style: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;height:1px !important;width:1px !important;border-top-width:0px !important;border-right-width:0px !important;border-bottom-width:0px !important;border-left-width:0px !important;margin-top:0px !important;margin-right:0px !important;margin-bottom:0px !important;margin-left:0px !important;padding-top:0px !important;padding-right:0px !important;padding-bottom:0px !important;padding-left:0px !important;" border="0" height="1" width="1" alt="" src="https://www.fastmailusercontent.com/proxy/b3e0c13db481262d6eeccbdc24023a1d21bacea9c9da95b00874d6ec4d75be7a/8647470737a3f2f25723030323431303e23647e23756e64676279646e2e65647f27766f2f60756e6f35707e6d3a466d40516d22364737777a505a737a53315b41483e4a647f4e49495854335a626755755874707663745952386677463937336a785a636774685e69755c65703263466a637a5e464937393d22324d605948413453473d6c64533850513964573a4e656a4645696e65687235437443584a70785a723958475852355f4750337a4c68587944557b6f474658316d22324653447d22324445315e6d223646456643556754303d223642477d454e4c4371727837746950373c4a6a5a78315956656a78503c634c637666767d22364c653a695441633c6e4a533a796d4957453f6363454d64786851445f6149554e636a4c43625778434a5b6a48737d23344/open" class=""><span class="font" style="font-family:AvenirNext-Medium"><span class="size" style="font-size:15px"><span class=""></span>_______________________________________________</span></span><br class=""></div>
<div class=""><span class="font" style="font-family:AvenirNext-Medium"><span class="size" style="font-size:15px">swift-evolution mailing list</span></span><br class=""></div>
<div class=""><a style="font-family:AvenirNext-Medium;font-size:15px;font-style: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;" href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a><br class=""></div>
<div class=""><a style="font-family:AvenirNext-Medium;font-size:15px;font-style: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;" href="https://lists.swift.org/mailman/listinfo/swift-evolution" class="">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br class=""></div>
</div>
</blockquote></div>
<div class=""> </div>
</div>
</div>
</blockquote></div>
<div class=""> </div>
<div class=""> <img style="height:1px !important;width:1px !important;border-top-width:0px !important;border-right-width:0px !important;border-bottom-width:0px !important;border-left-width:0px !important;margin-top:0px !important;margin-bottom:0px !important;margin-right:0px !important;margin-left:0px !important;padding-top:0px !important;padding-bottom:0px !important;padding-right:0px !important;padding-left:0px !important;" border="0" height="1" width="1" alt="" src="https://www.fastmailusercontent.com/proxy/1e5a7b315d7c541d19742122465d80cd1bc4f7fb82049f66cc3aeb66180242e2/8647470737a3f2f25723030323431303e23647e23756e64676279646e2e65647f27766f2f60756e6f35707e6d3148765176786c673171614a7d2236454230345272776e4562464444696a4f43696f45407459545d22324770724666736c6a763d22324342473a4a7269327f6645776453507375346a6c60703e4f475a6a6d6939747962634d6633785f4a5577455d446b4274425a7e4466436f61575274675473726d223647516d2232466055775355666967545c405a694140337c40395a595975517059746e6259714352563f67566f603a4563464b4d64753d22324847637236527676354a7d22364b6c436a6744555d2232405a4743787743457e663a5242677d223646324f4452765a753e647b4e486968614d23344d23344/open" class=""><br class=""></div>
<div class=""><u class="">_______________________________________________</u><br class=""></div>
<div class="">swift-evolution mailing list<br class=""></div>
<div class=""><a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a><br class=""></div>
<div class=""><a href="https://lists.swift.org/mailman/listinfo/swift-evolution" class="">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br class=""></div>
</blockquote><div class=""> </div>
<img src="https://u2002410.ct.sendgrid.net/wf/open?upn=9EwXyNl81W9TT3yZ17PL28-2Be7Ks-2FXLjqa0dZcsddi5bZZaXMMPW9WShMeBicv7lfgLbaLR3su9f7-2BTWOn-2FKs8JYbGQNz7sBiaG2raBACmYFmR4tkL5XN5FvCHdQo486Wv4vEp-2FGIG5kSeHSksyQCb9GWxEXJbH3rtfSX-2BZy73O-2BTczQN2k7snycldvyM-2BQ4PXtn0EK52TU6qQKFBuiJ9WRU7mGSB9Vv70bhRnzr1n40-3D" alt="" width="1" height="1" border="0" style="height:1px !important;width:1px !important;border-width:0 !important;margin-top:0 !important;margin-bottom:0 !important;margin-right:0 !important;margin-left:0 !important;padding-top:0 !important;padding-bottom:0 !important;padding-right:0 !important;padding-left:0 !important;" class="">
</div>
_______________________________________________<br class="">swift-evolution mailing list<br class=""><a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a><br class="">https://lists.swift.org/mailman/listinfo/swift-evolution<br class=""></div></blockquote></div><br class=""></body></html>