<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="">While I’d love to see HKTs in Swift in the future, and it’s definitely the feature I’m most excited about, I think I’m -1 on this proposal for Swift 3.<div class=""><br class=""></div><div class="">I’m not sure if I’m formally correct here, but here’s my understanding so far: Swift’s current type system is powerful enough to express all of the individual Monads that we’re interested in, but it is <i class="">not</i>&nbsp;capable of a Monad protocol. (or a functor, or applicative, etc.)</div><div class=""><br class=""></div><div class="">If that’s the case, then I can see only two advantages to HKTs:</div><div class=""><br class=""></div><div class=""><ul class="MailOutline"><li class="">Code reuse for monadic functions, such as mapM, sequence, etc.</li><li class="">The ability to reason and code about monads generally, rather than about specific monads.</li></ul><div class=""><br class=""></div><div class="">I think the first advantage is the “getting functions for free” idea. However, I’m not sure how much of an advantage it really is: the minimal complete definition for Monad is map, flatMap, and pure. Is mapM and sequence really such an extra hassle? Don’t get me wrong: <i class="">not</i>&nbsp;having to define them is obviously preferable. I’m just not sure <i class="">how</i>&nbsp;preferable.</div><div class=""><br class=""></div><div class="">The second advantage, while it’s something <i class="">I’m</i>&nbsp;certainly interested in, seems much more difficult to justify as an investment of the Swift team’s time. &nbsp;As someone who’s been learning Haskell for 6-ish months now, I’m only just beginning to grasp those more abstract concepts, and even then it’s still just fun and interesting, rather than useful. I can’t imagine a lot of Comonadic Costate Coalgebra whatever making it into production code.</div><div class=""><br class=""></div><div class="">I feel like right now Swift can get 80% of the benefits from Monadic code, since we can already write Optional, Gen, Parser, State, Par, etc.</div><div class=""><br class=""></div><div class=""><div><blockquote type="cite" class=""><div class="">On 17 Dec 2015, at 16:44, Thorsten Seitz via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>&gt; wrote:</div><br class="Apple-interchange-newline"><div class=""><div 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><div 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="">Big +1 for HKTs from me!</div><div 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=""><br class=""></div><div 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="">-Thorsten&nbsp;</div><div 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=""><br class="">Am 17.12.2015 um 13:10 schrieb Will Fancher via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>&gt;:<br class=""><br class=""></div><blockquote type="cite" 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=""><div class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><blockquote type="cite" class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><div class=""><div class="">Optional.map and Array.map do different things, and unifying them seems harmful.</div></div></div></blockquote><div class=""><br class=""></div><div class="">In terms of category theory, they're not different. They are both arrows from a to b in the Functor category. Obviously that's horribly abstract, so I'll put it this way: If you think of these map functions not as operations on Optional and Array, and instead think of them simply as ways to compose an arbitrary data structure, they are in fact doing the same thing. On an implementation level, and on a runtime level, they perform differently. But on a type level, a theoretical level, and a categorical level, they are the same. You merely need to accept that when using this abstraction without knowledge of the concrete type, you have no reason to make any assumptions about how the implementation and runtime will behave. At that point, all you need is to be sure that the Functor being passed in abides by the Functor laws, and that's just a matter of convention.</div><div class=""><br class=""></div><div class=""><blockquote type="cite" class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><div class="">First, I consider myself a smart person with a very broad experience with non-functional languages, but reading this makes my mind hurt, a lot:</div><div class=""><br class=""></div><div class=""><div class=""><blockquote type="cite" class=""><div class=""><div class="">&nbsp; &nbsp;typeclass Functor f where<br class="">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fmap :: (a -&gt; b) -&gt; f a -&gt; f b</div></div></blockquote>&lt;snip&gt;<br class=""><blockquote type="cite" class=""><div class=""><div class="">This makes it possible to build functions which operate not just on Maybe, but on any Functor.</div></div></blockquote><blockquote type="cite" class=""><div class=""><div class=""><br class="">&nbsp;&nbsp;&nbsp;fstrlen :: Functor f =&gt; f String -&gt; f Int<br class="">&nbsp;&nbsp;&nbsp;fstrlen fstr = fmap length faster</div></div></blockquote>&lt;snip&gt;<br class=""><blockquote type="cite" class=""><div class=""><div class="">&nbsp; &nbsp;protocol Functor {<br class="">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;typealias A<br class="">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;func fmap&lt;FB where FB ~= Self&gt;(f: A -&gt; FB.A) -&gt; FB<br class="">&nbsp;&nbsp;&nbsp;}<br class=""></div></div></blockquote><div class=""><br class=""></div><div class="">I understand what's going on here, but I never, ever want to see this code anywhere near (my) Swift.</div></div></div></div></blockquote><br class=""></div><div class="">HKTs that come from category theory tend to have this effect. They are hard to understand by reading the protocol definition. Admittedly, this is a big flaw with Monads and with Haskell. It takes a reasonable understanding of category theory for the purpose of this code to be obvious to the reader.</div><div class=""><br class=""></div><div class="">(I will point out that in those code examples, I used absolutely abysmal naming conventions. It could be made marginally more readable and understandable if the naming were better)</div><div class=""><br class=""></div><div class="">I'll take this time to make the point that just because you don't like the way the Functor protocol looks, doesn't mean Array and Optional aren't both Functors and Monads. As a matter of mathematics, if the Monad functions can exist on a type, and they would follow the Monad laws, that type is a Monad whether the implementor likes it or not. Of course it still needs manual implementing, but regardless, the type is theoretically a Monad. (This realization is the reason that the Java team decided to implement flatMap for Java 8's Optional class.)</div><div class=""><br class=""></div><div class=""><blockquote type="cite" class="">I believe the way to convince the rest of us (and I would love to be convinced) is to provide a few real, “end-user” app-level use cases and explain the benefit in plain language. In particular, I don't understand the example by Jens Persson, although it seems like a valuable one.</blockquote></div><br class=""><div class="">I can (again) link to just a few of the abstract Monadic functions, all of which are very useful in practical applications.</div><div class=""><br class=""></div><div class=""><a href="https://hackage.haskell.org/package/base-4.8.1.0/docs/Control-Monad.html" class="">https://hackage.haskell.org/package/base-4.8.1.0/docs/Control-Monad.html</a></div><div class=""><br class=""></div><div class="">But perhaps it would also help to describe the architectural decisions that abiding by Monad imposes.</div><div class=""><br class=""></div><div class="">Being Monadic makes you think about data composition, which cleans up the way you design your code. Going back to the Futures example, I could implement future, and subsequently use it, like this:</div><div class=""><br class=""></div><div class=""><div class="">&nbsp; &nbsp; public class Promise&lt;T&gt; {</div><div class="">&nbsp; &nbsp; &nbsp; &nbsp; private var handlers: [T -&gt; ()] = []</div><div class="">&nbsp; &nbsp; &nbsp; &nbsp; private var completed: T? = nil</div><div class="">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;</div><div class="">&nbsp; &nbsp; &nbsp; &nbsp; public init() {</div><div class="">&nbsp; &nbsp; &nbsp; &nbsp; }</div><div class="">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;</div><div class="">&nbsp; &nbsp; &nbsp; &nbsp; private func onComplete(handler: T -&gt; ()) {</div><div class="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if let completed = completed {</div><div class="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; handler(completed)</div><div class="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } else {</div><div class="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; handlers.append(handler)</div><div class="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }</div><div class="">&nbsp; &nbsp; &nbsp; &nbsp; }</div><div class="">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;</div><div class="">&nbsp; &nbsp; &nbsp; &nbsp; public func complete(t: T) {</div><div class="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; completed = t</div><div class="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; for handler in handlers {</div><div class="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; handler(t)</div><div class="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }</div><div class="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; handlers = []</div><div class="">&nbsp; &nbsp; &nbsp; &nbsp; }</div><div class="">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;</div><div class="">&nbsp; &nbsp; &nbsp; &nbsp; public var future: Future&lt;T&gt; {</div><div class="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return Future(promise: self)</div><div class="">&nbsp; &nbsp; &nbsp; &nbsp; }</div><div class="">&nbsp; &nbsp; }</div><div class=""><br class=""></div><div class="">&nbsp; &nbsp; public struct Future&lt;T&gt; {</div><div class="">&nbsp; &nbsp; &nbsp; &nbsp; private let promise: Promise&lt;T&gt;</div><div class="">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;</div><div class="">&nbsp; &nbsp; &nbsp; &nbsp; private init(promise: Promise&lt;T&gt;) {</div><div class="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; self.promise = promise</div><div class="">&nbsp; &nbsp; &nbsp; &nbsp; }</div><div class="">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;</div><div class="">&nbsp; &nbsp; &nbsp; &nbsp; public func onComplete(handler: T -&gt; ()) {</div><div class="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; promise.onComplete(handler)</div><div class="">&nbsp; &nbsp; &nbsp; &nbsp; }</div><div class="">&nbsp; &nbsp; }</div><div class=""><br class=""></div><div class="">&nbsp; &nbsp; public func useFutures() {</div><div class="">&nbsp; &nbsp; &nbsp; &nbsp; downloadURLInFuture().onComplete { content in</div><div class="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; processContentAsync(content).onComplete { processed in</div><div class="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; processed.calculateSomethingAsync().onComplete {</div><div class="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ...</div><div class="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ...</div><div class="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; print(finalProduct)</div><div class="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ...</div><div class="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ...</div><div class="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }</div><div class="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }</div><div class="">&nbsp; &nbsp; &nbsp; &nbsp; }</div><div class="">&nbsp; &nbsp; }</div></div><div class=""><br class=""></div><div class="">You can see how this resembles the infamous Node.js issue of callback hell, and how the nesting could quickly get out of hand. If only we had some form of composition... Arrows between Futures... Luckily, Future is a Monad (whether I like it or not!)</div><div class=""><br class=""></div><div class=""><div class="">&nbsp; &nbsp; // Monad</div><div class=""><br class=""></div><div class="">&nbsp; &nbsp; public extension Future {</div><div class="">&nbsp; &nbsp; &nbsp; &nbsp; public static func point&lt;T&gt;(t: T) -&gt; Future&lt;T&gt; {</div><div class="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; let promise = Promise&lt;T&gt;()</div><div class="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; promise.complete(t)</div><div class="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return promise.future</div><div class="">&nbsp; &nbsp; &nbsp; &nbsp; }</div><div class="">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;</div><div class="">&nbsp; &nbsp; &nbsp; &nbsp; public func flatMap&lt;U&gt;(f: T -&gt; Future&lt;U&gt;) -&gt; Future&lt;U&gt; {</div><div class="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; let uPromise = Promise&lt;U&gt;()</div><div class="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;</div><div class="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; onComplete { t in</div><div class="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; f(t).onComplete { u in</div><div class="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; uPromise.complete(u)</div><div class="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }</div><div class="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }</div><div class="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;</div><div class="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return uPromise.future</div><div class="">&nbsp; &nbsp; &nbsp; &nbsp; }</div><div class="">&nbsp; &nbsp; }</div></div><div class=""><br class=""></div><div class="">Not only do I now get map and apply for free, but I also get a great method of composing Futures. The example from above can now be rewritten to be much more well composed.</div><div class=""><br class=""></div><div class=""><div class="">&nbsp; &nbsp; public func useFutures() {</div><div class="">&nbsp; &nbsp; &nbsp; &nbsp; downloadURLInFuture()</div><div class="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .flatMap(processContentAsync)</div><div class="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .flatMap { $0.calculateSomethingAsync() }</div><div class="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ...</div><div class="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .onComplete { finalProduct in</div><div class="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; print(finalProduct)</div><div class="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }</div><div class="">&nbsp; &nbsp; }</div></div><div class=""><br class=""></div><div class="">The important thing here is that thinking about Monads helped me discover a better composition model. Now my code can be more readable and well composed.</div><div class=""><br class=""></div></div></div><div class="">And again, I'll mention the enormous world of functions and capabilities that can be gotten for free for the sake of even more well-composed code.</div><br class=""><div class=""><blockquote type="cite" class=""><div class="">I don't want a flatMap on optionals (which, I believe, was thankfully removed in Swift 2).</div></blockquote><br class=""></div><div class="">And why on Earth not? The concrete implementation of it on Optional is very simple and easy to understand, and the method is incredibly useful. Personally, I use it all the time (it was not removed). And again, just because you don't like using flatMap doesn't mean Optional isn't a Monad.</div><div class=""><br class=""></div><div class="">Finally, I'd like to point out that it doesn't hurt any end users not familiar with Monads if Array implements a higher kinded Monad protocol. As far as they have to be concerned, Array just has these useful map and flatMap functions. Meanwhile, those of us who wish to abstract over Monads in general can write our abstract code and implement Monad on our various types which mathematically have to be Monads. It's a layer of robustness and improvement that unconcerned end users don't have to bother themselves with.</div><div class=""><br class=""></div><div class="">While I understand that the Swift team doesn't have the resources to implement everything that everyone wants, and that HKTs aren't very high on their list of priorities, it seems unreasonable to me that one could think of HKTs and Monads as somehow detrimental to the language.</div><img src="https://u2002410.ct.sendgrid.net/wf/open?upn=1MXK54sosN3xru3iYcLt0oBZ2w20i49gyogXctgrspdifEc60hd-2FHHx-2FDnKudeVTXrrb-2FFnn4MJmMn8vFm01f3NiitschCpQupPvTkee0q5FSL5bHWTN9CBSedsJCI7y1MHrWE7o3WykKEUEhI3BQxvyqghzMvUvsR-2FICpnwQ-2FrBNHzYDuIwRbx6iNRIPr7k0mFmglrz02DzbkZ40DHDRE3d-2Fe80x7jFEZaUG7rkXH8-3D" alt="" width="1" height="1" border="0" style="height: 1px !important; width: 1px !important; border-width: 0px !important; margin: 0px !important; padding: 0px !important;" class=""></div></blockquote><blockquote type="cite" 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=""><span class="">_______________________________________________</span><br class=""><span class="">swift-evolution mailing list</span><br class=""><span class=""><a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a></span><br class=""><span class=""><a href="https://lists.swift.org/mailman/listinfo/swift-evolution" class="">https://lists.swift.org/mailman/listinfo/swift-evolution</a></span><br class=""></div></blockquote><img src="https://u2002410.ct.sendgrid.net/wf/open?upn=Lo8TP3b1oIn3yQXUt9zA1UCQfR-2BMBCuqnubTuDg47-2B3jpD2OX74-2FV-2FeFWtq0habXt7YZtXDV9PbEFOEOHFOSGe7Rjxw1HsXAZnsTG-2BwOFU3KGFHsmTonfqAEHklKLDaTbnAvFa-2F9L-2BXrAU3csWL17-2Brby52tVDs7LPSyi01TDo2SUYBahY1TmH6cKNIWxZCzWbfFinfX8F8BMfRVA4Vt1RMQTa-2FP5M6HEjPt-2BqAUYtw-3D" alt="" width="1" height="1" border="0" 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; height: 1px !important; width: 1px !important; border-width: 0px !important; margin: 0px !important; padding: 0px !important;" class=""><span 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; float: none; display: inline !important;" class=""><span class="Apple-converted-space">&nbsp;</span>_______________________________________________</span><br 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=""><span 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; float: none; display: inline !important;" class="">swift-evolution mailing list</span><br 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=""><a href="mailto:swift-evolution@swift.org" 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="">swift-evolution@swift.org</a><br 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=""><a href="https://lists.swift.org/mailman/listinfo/swift-evolution" 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="">https://lists.swift.org/mailman/listinfo/swift-evolution</a></div></blockquote></div><br class=""></div></div></body></html>