Yes, thank you!<br><div class="gmail_quote"><div dir="ltr">On Sun, Jan 10, 2016 at 10:28 PM Kevin Ballard &lt;<a href="mailto:kevin@sb.org">kevin@sb.org</a>&gt; wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><u></u>




<div><div>Sounds like you want usage examples, then. Are the ones I gave useful?</div></div><div>
<div> </div>
<div>-Kevin Ballard</div></div><div>
<div> </div>
<div>On Sun, Jan 10, 2016, at 10:26 PM, Seth Friedman wrote:<br></div>
<blockquote type="cite"><div>I wasn&#39;t suggesting you should convince the reviewers of the merits of functional style programming. I&#39;m coming at it from the perspective of &quot;Hey I&#39;m not very familiar with functional style. What cool new things could these functions help me do if they&#39;re added to the stdlib?&quot;.<br></div>
<div> </div>
<div>Not all of your reviewers are necessarily going to be familiar with these functions from other languages; I simply think more detail would make the proposal more compelling. Ultimately up to you.<br></div>
<div> </div>
<div>Thanks,<br></div>
<div>Seth<br></div>
<div><div dir="ltr">On Sun, Jan 10, 2016 at 10:20 PM Kevin Ballard &lt;<a href="mailto:kevin@sb.org" target="_blank">kevin@sb.org</a>&gt; wrote:<br></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"><div style="word-wrap:break-word"><div>When the proposal is &quot;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&quot;, does there really need to be much explanation beyond &quot;they&#39;re useful in the other languages that have them, they&#39;d be useful for the same reasons in Swift&quot;?<br></div>
<div> </div>
<div>If requested, I can provide examples of usage. But if you&#39;re not already sold on the benefits of working with sequences in a functional manner, it&#39;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&#39;t need much explanation.<br></div>
<div> </div>
<div>Here&#39;s a few toy examples, if it helps:<br></div>
<div> </div>
<div><div style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(0,132,0)">// list of all powers of 2 below some limit<br></div>
<div style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;font-size:11px;line-height:normal;font-family:Menlo">iterate(<span style="color:rgb(39,42,216)">1</span>, apply: { $0 * <span style="color:rgb(39,42,216)">2</span> }).takeWhile({ $0 &lt; limit })<br></div>
<div style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;font-size:11px;line-height:normal;font-family:Menlo;min-height:13px"> </div>
<div style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(0,132,0)">// first &quot;word&quot; of a string, skipping whitespace<br></div>
<div style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;font-size:11px;line-height:normal;font-family:Menlo"><span style="color:rgb(187,44,162)">let</span> cs = NSCharacterSet.whitespaceCharacterSet()<br></div>
<div style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;font-size:11px;line-height:normal;font-family:Menlo">String(str.unicodeScalars.skipWhile({ cs.longCharacterIsMember($0.value) })<br></div>
<div style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;font-size:11px;line-height:normal;font-family:Menlo">                         .takeWhile({ !cs.longCharacterIsMember($0.value) }))<br></div>
<div style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;font-size:11px;line-height:normal;font-family:Menlo;min-height:13px"> </div>
<div style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(0,132,0)">// running total of an array of numbers<br></div>
<div style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;font-size:11px;line-height:normal;font-family:Menlo">numbers.scan(<span style="color:rgb(39,42,216)">0</span>, combine: +).dropFirst()<br></div>
<div style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;font-size:11px;line-height:normal;font-family:Menlo;min-height:13px"> </div>
<div style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(0,132,0)">// infinite fibonacci sequence<br></div>
<div style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;font-size:11px;line-height:normal;font-family:Menlo">iterate((<span style="color:rgb(39,42,216)">0</span>,<span style="color:rgb(39,42,216)">1</span>), apply: { ($1, $0+$1) }).lazy.map({$1})<br></div>
</div>
</div>
<div style="word-wrap:break-word"><div> </div>
<div>-Kevin Ballard<br></div>
</div>
<div style="word-wrap:break-word"><div> </div>
<div>On Sun, Jan 10, 2016, at 09:55 PM, Seth Friedman wrote:<br></div>
<blockquote type="cite"><div>To clear my thoughts up a bit, that wasn&#39;t an &quot;I&#39;m too lazy to Google what these functions normally do&quot; comment, but rather an &quot;I believe proposals should provide as much context as possible about what you&#39;d like to add along with the benefits of doing so&quot; comment.<br></div>
<div><div dir="ltr">On Sun, Jan 10, 2016 at 9:48 PM Seth Friedman &lt;<a href="mailto:sethfri@gmail.com" target="_blank">sethfri@gmail.com</a>&gt; wrote:<br></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"><div>I&#39;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></div>
<div> </div>
<div>Thanks!<br></div>
<div> </div>
<div>Seth<br></div>
<div><div dir="ltr">On Sat, Jan 9, 2016 at 5:30 PM Kevin Ballard via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>&gt; wrote:<br></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"><div>Proposal PR submitted as <a href="https://github.com/apple/swift-evolution/pull/95" target="_blank">https://github.com/apple/swift-evolution/pull/95</a><br></div>
<div> </div>
<div>-Kevin Ballard<br></div>
<div> </div>
<div>On Mon, Dec 28, 2015, at 03:59 PM, Kevin Ballard wrote:<br></div>
<div>&gt; ## Introduction<br></div>
<div>&gt;<br></div>
<div>&gt; Add a few more functional sequence utilities to the standard library.<br></div>
<div>&gt;<br></div>
<div>&gt; ## Motivation<br></div>
<div>&gt;<br></div>
<div>&gt; We have map, filter, and reduce, but we&#39;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&#39;t actually provide it as API.<br></div>
<div>&gt;<br></div>
<div>&gt; ## Proposed solution<br></div>
<div>&gt;<br></div>
<div>&gt; We extend SequenceType with 3 new methods scan, takeWhile, and dropWhile. We also add a single global function iterate.<br></div>
<div>&gt;<br></div>
<div>&gt; ## Detailed design<br></div>
<div>&gt;<br></div>
<div>&gt; We add the following extension to SequenceType:<br></div>
<div>&gt;<br></div>
<div>&gt; extension SequenceType {<br></div>
<div>&gt;     func scan&lt;T&gt;(initial: T, @noescape combine: (T, Self.Generator.Element) throws -&gt; T) rethrows -&gt; [T]<br></div>
<div>&gt;     func dropWhile(@noescape dropElement: (Self.Generator.Element) throws -&gt; Bool) rethrows -&gt; [Self.Generator.Element]<br></div>
<div>&gt;     func takeWhile(@noescape takeElement: (Self.Generator.Element) throws -&gt; Bool) rethrows -&gt; [Self.Generator.Element]<br></div>
<div>&gt; }<br></div>
<div>&gt;<br></div>
<div>&gt; These all take functions, so to follow convention they&#39;re @noescape and return arrays. We also provide an extension of CollectionType that overrides a couple of these methods:<br></div>
<div>&gt;<br></div>
<div>&gt; extension CollectionType {<br></div>
<div>&gt;     func dropWhile(@noescape dropElement: (Self.Generator.Element) throws -&gt; Bool) rethrows -&gt; Self.SubSequence<br></div>
<div>&gt;     func takeWhile(@noescape takeElement: (Self.Generator.Element) throws -&gt; Bool) rethrows -&gt; Self.SubSequence<br></div>
<div>&gt; }<br></div>
<div>&gt;<br></div>
<div>&gt; We also provide lazy versions:<br></div>
<div>&gt;<br></div>
<div>&gt; extension LazySequenceType {<br></div>
<div>&gt;     func scan&lt;T&gt;(initial: T, combine: (T, Self.Generator.Element) -&gt; T) -&gt; LazyScanSequence&lt;Self.Elements, T&gt;<br></div>
<div>&gt;     func dropWhile(dropElement: (Self.Generator.Element) -&gt; Bool) -&gt; LazyDropWhileSequence&lt;Self.Elements&gt;<br></div>
<div>&gt;     func takeWhile(takeElement: (Self.Generator.Element) -&gt; Bool) -&gt; LazyTakeWhileSequence&lt;Self.Elements&gt;<br></div>
<div>&gt; }<br></div>
<div>&gt;<br></div>
<div>&gt; extension LazyCollectionType {<br></div>
<div>&gt;     func dropWhile(dropElement: (Self.Generator.Element) -&gt; Bool) -&gt; LazyDropWhileCollection&lt;Self.Elements&gt;<br></div>
<div>&gt;     func takeWhile(takeElement: (Self.Generator.Element) -&gt; Bool) -&gt; LazyTakeWhileCollection&lt;Self.Elements&gt;<br></div>
<div>&gt; }<br></div>
<div>&gt;<br></div>
<div>&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&#39;t pure.<br></div>
<div>&gt;<br></div>
<div>&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&#39;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&#39;t know where the end is until you reach that point; this index type would therefore only conform to ForwardIndexType).<br></div>
<div>&gt;<br></div>
<div>&gt; And finally, we provide a global function<br></div>
<div>&gt;<br></div>
<div>&gt; func iterate&lt;T&gt;(initial: T, _ f: T -&gt; T) -&gt; IterateSequence&lt;T&gt;<br></div>
<div>&gt;<br></div>
<div>&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></div>
<div>&gt;<br></div>
<div>&gt; -Kevin Ballard<br></div>
<div>_______________________________________________<br></div>
<div>swift-evolution mailing list<br></div>
<div><a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a><br></div>
<div><a href="https://lists.swift.org/mailman/listinfo/swift-evolution" target="_blank">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br></div>
</blockquote></div>
</blockquote></div>
</blockquote><div> </div>
</div>
</blockquote></div>
</blockquote><div> </div>
</div></blockquote></div>