<html><head><meta http-equiv="Content-Type" content="text/html charset=us-ascii">
<title></title>
</head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class="">When the proposal is "we have a bunch of functions that match functions used in other languages, lets add a few more from the same category of functions that we missed", does there really need to be much explanation beyond "they're useful in the other languages that have them, they'd be useful for the same reasons in Swift"?<br class=""></div>
<div class=""><br class=""></div>
<div class="">If requested, I can provide examples of usage. But if you're not already sold on the benefits of working with sequences in a functional manner, it's out of scope of the proposal to convince you of the merits of that style of programming. And if you are already sold on the benefits of doing so, then adding these functions shouldn't need much explanation.<br class=""></div>
<div class=""><br class=""></div>
<div class="">Here's a few toy examples, if it helps:<br class=""></div>
<div class=""><br class=""></div><div class=""><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(0, 132, 0);" class="">// list of all powers of 2 below some limit</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class="">iterate(<span style="font-variant-ligatures: no-common-ligatures; color: #272ad8" class="">1</span>, apply: { $0 * <span style="font-variant-ligatures: no-common-ligatures; color: #272ad8" class="">2</span> }).takeWhile({ $0 &lt; limit })</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; min-height: 13px;" class=""><br class=""></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(0, 132, 0);" class="">// first "word" of a string, skipping whitespace</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">let</span> cs = NSCharacterSet.whitespaceCharacterSet()</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class="">String(str.unicodeScalars.skipWhile({ cs.longCharacterIsMember($0.value) })</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class="">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .takeWhile({ !cs.longCharacterIsMember($0.value) }))</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; min-height: 13px;" class=""><br class=""></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(0, 132, 0);" class="">// running total of an array of numbers</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class="">numbers.scan(<span style="font-variant-ligatures: no-common-ligatures; color: #272ad8" class="">0</span>, combine: +).dropFirst()</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; min-height: 13px;" class=""><br class=""></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(0, 132, 0);" class="">// infinite fibonacci sequence</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class="">iterate((<span style="font-variant-ligatures: no-common-ligatures; color: #272ad8" class="">0</span>,<span style="font-variant-ligatures: no-common-ligatures; color: #272ad8" class="">1</span>), apply: { ($1, $0+$1) }).lazy.map({$1})</div></div>
<div class=""><br class=""></div>
<div class="">-Kevin Ballard</div>
<div class=""><br class=""></div>
<div class="">On Sun, Jan 10, 2016, at 09:55 PM, Seth Friedman wrote:<br class=""></div>
<blockquote type="cite" class=""><div class="">To clear my thoughts up a bit, that wasn't an "I'm too lazy to Google what these functions normally do" comment, but rather an "I believe proposals should provide as much context as possible about what you'd like to add along with the benefits of doing so" comment.<br class=""></div>
<div class=""><div dir="ltr" class="">On Sun, Jan 10, 2016 at 9:48 PM Seth Friedman &lt;<a href="mailto:sethfri@gmail.com" class="">sethfri@gmail.com</a>&gt; wrote:<br class=""></div>
<blockquote style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0.8ex;border-left-width:1px;border-left-color:rgb(204, 204, 204);border-left-style:solid;padding-left:1ex;" class=""><div class="">I'm not familiar with any of the functions listed and would love to see more about them and their usefulness to Swift as part of the proposal.<br class=""></div>
<div class="">&nbsp;</div>
<div class="">Thanks!<br class=""></div>
<div class="">&nbsp;</div>
<div class="">Seth<br class=""></div>
<div class=""><div dir="ltr" class="">On Sat, Jan 9, 2016 at 5:30 PM Kevin Ballard via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>&gt; wrote:<br class=""></div>
<blockquote style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0.8ex;border-left-width:1px;border-left-color:rgb(204, 204, 204);border-left-style:solid;padding-left:1ex;" class=""><div class="">Proposal PR submitted as <a href="https://github.com/apple/swift-evolution/pull/95" class="">https://github.com/apple/swift-evolution/pull/95</a><br class=""></div>
<div class="">&nbsp;</div>
<div class="">
-Kevin Ballard<br class=""></div>
<div class="">&nbsp;</div>
<div class="">
On Mon, Dec 28, 2015, at 03:59 PM, Kevin Ballard wrote:<br class=""></div>
<div class="">
&gt; ## Introduction<br class=""></div>
<div class="">
&gt;<br class=""></div>
<div class="">
&gt; Add a few more functional sequence utilities to the standard library.<br class=""></div>
<div class="">
&gt;<br class=""></div>
<div class="">
&gt; ## Motivation<br class=""></div>
<div class="">
&gt;<br class=""></div>
<div class="">
&gt; We have map, filter, and reduce, but we're missing a bunch of useful utilities like scan, iterate, takeWhile, and dropWhile. Interestingly, the stdlib includes an implementation of scan in the doc comment for LazySequenceType, it just doesn't actually provide it as API.<br class=""></div>
<div class="">
&gt;<br class=""></div>
<div class="">
&gt; ## Proposed solution<br class=""></div>
<div class="">
&gt;<br class=""></div>
<div class="">
&gt; We extend SequenceType with 3 new methods scan, takeWhile, and dropWhile. We also add a single global function iterate.<br class=""></div>
<div class="">
&gt;<br class=""></div>
<div class="">
&gt; ## Detailed design<br class=""></div>
<div class="">
&gt;<br class=""></div>
<div class="">
&gt; We add the following extension to SequenceType:<br class=""></div>
<div class="">
&gt;<br class=""></div>
<div class="">
&gt; extension SequenceType {<br class=""></div>
<div class="">
&gt;&nbsp; &nbsp; &nbsp;func scan&lt;T&gt;(initial: T, @noescape combine: (T, Self.Generator.Element) throws -&gt; T) rethrows -&gt; [T]<br class=""></div>
<div class="">
&gt;&nbsp; &nbsp; &nbsp;func dropWhile(@noescape dropElement: (Self.Generator.Element) throws -&gt; Bool) rethrows -&gt; [Self.Generator.Element]<br class=""></div>
<div class="">
&gt;&nbsp; &nbsp; &nbsp;func takeWhile(@noescape takeElement: (Self.Generator.Element) throws -&gt; Bool) rethrows -&gt; [Self.Generator.Element]<br class=""></div>
<div class="">
&gt; }<br class=""></div>
<div class="">
&gt;<br class=""></div>
<div class="">
&gt; These all take functions, so to follow convention they're @noescape and return arrays. We also provide an extension of CollectionType that overrides a couple of these methods:<br class=""></div>
<div class="">
&gt;<br class=""></div>
<div class="">
&gt; extension CollectionType {<br class=""></div>
<div class="">
&gt;&nbsp; &nbsp; &nbsp;func dropWhile(@noescape dropElement: (Self.Generator.Element) throws -&gt; Bool) rethrows -&gt; Self.SubSequence<br class=""></div>
<div class="">
&gt;&nbsp; &nbsp; &nbsp;func takeWhile(@noescape takeElement: (Self.Generator.Element) throws -&gt; Bool) rethrows -&gt; Self.SubSequence<br class=""></div>
<div class="">
&gt; }<br class=""></div>
<div class="">
&gt;<br class=""></div>
<div class="">
&gt; We also provide lazy versions:<br class=""></div>
<div class="">
&gt;<br class=""></div>
<div class="">
&gt; extension LazySequenceType {<br class=""></div>
<div class="">
&gt;&nbsp; &nbsp; &nbsp;func scan&lt;T&gt;(initial: T, combine: (T, Self.Generator.Element) -&gt; T) -&gt; LazyScanSequence&lt;Self.Elements, T&gt;<br class=""></div>
<div class="">
&gt;&nbsp; &nbsp; &nbsp;func dropWhile(dropElement: (Self.Generator.Element) -&gt; Bool) -&gt; LazyDropWhileSequence&lt;Self.Elements&gt;<br class=""></div>
<div class="">
&gt;&nbsp; &nbsp; &nbsp;func takeWhile(takeElement: (Self.Generator.Element) -&gt; Bool) -&gt; LazyTakeWhileSequence&lt;Self.Elements&gt;<br class=""></div>
<div class="">
&gt; }<br class=""></div>
<div class="">
&gt;<br class=""></div>
<div class="">
&gt; extension LazyCollectionType {<br class=""></div>
<div class="">
&gt;&nbsp; &nbsp; &nbsp;func dropWhile(dropElement: (Self.Generator.Element) -&gt; Bool) -&gt; LazyDropWhileCollection&lt;Self.Elements&gt;<br class=""></div>
<div class="">
&gt;&nbsp; &nbsp; &nbsp;func takeWhile(takeElement: (Self.Generator.Element) -&gt; Bool) -&gt; LazyTakeWhileCollection&lt;Self.Elements&gt;<br class=""></div>
<div class="">
&gt; }<br class=""></div>
<div class="">
&gt;<br class=""></div>
<div class="">
&gt; No collection variant of scan is provided because that would require storing the last value in the index itself, which would cause problems if the combine function isn't pure.<br class=""></div>
<div class="">
&gt;<br class=""></div>
<div class="">
&gt; LazyDropWhileCollection would behave similarly to LazyFilterCollection in that it runs the predicate against the elements to drop when accessing startIndex; unlike LazyFilterCollection, because there's nothing else to skip after that point, the index itself can actually be Self.Elements.Index (just like a slice). LazyTakeWhileCollection also runs the predicate against the first element when accessing startIndex, but it does need a unique index type (because endIndex has to be some sentinel value, as it doesn't know where the end is until you reach that point; this index type would therefore only conform to ForwardIndexType).<br class=""></div>
<div class="">
&gt;<br class=""></div>
<div class="">
&gt; And finally, we provide a global function<br class=""></div>
<div class="">
&gt;<br class=""></div>
<div class="">
&gt; func iterate&lt;T&gt;(initial: T, _ f: T -&gt; T) -&gt; IterateSequence&lt;T&gt;<br class=""></div>
<div class="">
&gt;<br class=""></div>
<div class="">
&gt; This function is inherently lazy and yields an infinite list of nested applications of the function, so iterate(x, f) yields a sequence like [x, f(x), f(f(x)), ...].<br class=""></div>
<div class="">
&gt;<br class=""></div>
<div class="">
&gt; -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>
</blockquote></div>
</blockquote><div class="">&nbsp;</div>


</body></html>