<div dir="ltr">Any arguments against adding it? Otherwise I&#39;ll draft up a short proposal tomorrow.</div><div class="gmail_extra"><br><div class="gmail_quote">On Tue, Jan 17, 2017 at 7:24 PM, Joe Groff via swift-evolution <span dir="ltr">&lt;<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="HOEnZb"><div class="h5"><br>
&gt; On Jan 16, 2017, at 8:10 PM, Dave Abrahams via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a>&gt; wrote:<br>
&gt;<br>
&gt;<br>
&gt; on Mon Jan 16 2017, Charles Srstka &lt;cocoadev-AT-charlessoft.com&gt; wrote:<br>
&gt;<br>
&gt;&gt; On Jan 16, 2017, at 6:42 PM, Dave Abrahams via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a>&gt; wrote:<br>
&gt;&gt;&gt;<br>
&gt;&gt;&gt;<br>
&gt;&gt;&gt; on Mon Jan 16 2017, Charles Srstka &lt;<a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a><br>
&gt;&gt;&gt; &lt;mailto:<a href="mailto:swift-evolution@swift.org">swift-evolution@swift.<wbr>org</a>&gt;&gt; wrote:<br>
&gt;&gt;&gt;<br>
&gt;&gt;<br>
&gt;&gt;&gt;&gt;&gt; On Jan 16, 2017, at 7:49 AM, Chris Eidhof via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a>&gt; wrote:<br>
&gt;&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt;&gt; Hi,<br>
&gt;&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt;&gt; How does everyone feel about adding a second version of `reduce` to<br>
&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt;&gt; `Sequence`? Instead of a `combine` function that&#39;s of type `(A,<br>
&gt;&gt;&gt;&gt;&gt; Element) -&gt; A`, it would be `(inout A, Element) -&gt; ()`. This way, we<br>
&gt;&gt;&gt;&gt;&gt; can write nice functionals algorithms, but have the benefits of<br>
&gt;&gt;&gt;&gt;&gt; inout (mutation within the function, and hopefully some copy<br>
&gt;&gt;&gt;&gt;&gt; eliminations).<br>
&gt;&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt;&gt; IIRC, Loïc Lecrenier first asked this on Twitter. I&#39;ve been using it<br>
&gt;&gt;&gt;&gt;&gt; ever since, because it can really improve readability (the possible<br>
&gt;&gt;&gt;&gt;&gt; performance gain is nice, too).<br>
&gt;&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt;&gt; Here&#39;s `reduce` with an `inout` parameter, including a sample:<br>
&gt;&gt;&gt;&gt;&gt; <a href="https://gist.github.com/chriseidhof/fd3e9aa621569752d1b04230f92969d7" rel="noreferrer" target="_blank">https://gist.github.com/<wbr>chriseidhof/<wbr>fd3e9aa621569752d1b04230f92969<wbr>d7</a><br>
&gt;&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt;&gt; --<br>
&gt;&gt;&gt;&gt;&gt; Chris Eidhof<br>
&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt; I did this in my own private code a while ago. There is one drawback, which is that Swift’s type<br>
&gt;&gt;&gt;&gt; inference system isn’t quite up to handling it. For example, doing this results in an “ambiguous<br>
&gt;&gt;&gt;&gt; reference to member” warning:<br>
&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt; range.reduce([Int]()) { $0.append($1) }<br>
&gt;&gt;&gt;<br>
&gt;&gt;&gt; The diagnostic could be better, but the compiler shouldn&#39;t let you do<br>
&gt;&gt;&gt; that, because it requires passing an unnamed temporary value ([Int]())<br>
&gt;&gt;&gt; as inout.<br>
&gt;&gt;<br>
&gt;&gt; No it doesn’t. The signature of the method is:<br>
&gt;&gt;<br>
&gt;&gt; func reduce&lt;A&gt;(_ initial: A, combine: (inout A, Iterator.Element) -&gt; ()) -&gt; A<br>
&gt;&gt;<br>
&gt;&gt; The unnamed temporary value is “initial” here, which is not passed as inout; the inout parameter is<br>
&gt;&gt; the first argument to the “combine” closure. The value represented by the ‘initial’ parameter is<br>
&gt;&gt; passed to the closure, true, but only after being stored in a not-unnamed ‘var’ variable, as you can<br>
&gt;&gt; see from the source of the proposed method:<br>
&gt;&gt;<br>
&gt;&gt; func reduce&lt;A&gt;(_ initial: A, combine: (inout A, Iterator.Element) -&gt; ()) -&gt; A {<br>
&gt;&gt;    var result = initial<br>
&gt;&gt;    for element in self {<br>
&gt;&gt;        combine(&amp;result, element)<br>
&gt;&gt;    }<br>
&gt;&gt;    return result<br>
&gt;&gt; }<br>
&gt;&gt;<br>
&gt;&gt; Therefore, I don’t understand this objection.<br>
&gt;&gt;<br>
&gt;&gt;&gt;&gt; One would think that the type of this closure should be clear:<br>
&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt; 1) The closure calls append(), a mutating function, so $0 must be inout.<br>
&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt; 2) The closure doesn’t return anything, which should rule out the<br>
&gt;&gt;&gt;&gt; default implementations of reduce,<br>
&gt;&gt;&gt;<br>
&gt;&gt;&gt; The closure *does* return something: (), the empty tuple<br>
&gt;&gt;<br>
&gt;&gt; But it’s not what it’s supposed to return. Sequence’s implementation<br>
&gt;&gt; of reduce, which the compiler thinks matches the above, is declared<br>
&gt;&gt; like this:<br>
&gt;&gt;<br>
&gt;&gt; public func reduce&lt;Result&gt;(_ initialResult: Result, _<br>
&gt;&gt; nextPartialResult: (Result, Self.Iterator.Element) throws -&gt; Result)<br>
&gt;&gt; rethrows -&gt; Result<br>
&gt;&gt;<br>
&gt;&gt; The closure is supposed to return Result, which in this case would be<br>
&gt;&gt; [Int]. It doesn’t, so I’m not sure why the compiler is thinking this<br>
&gt;&gt; is a match.<br>
&gt;<br>
&gt; Okay, sounds like I&#39;m totally wrong! Has to happen at least once in a<br>
&gt; lifetime, doesn&#39;t it? 😉<br>
&gt;<br>
&gt; So please file bug reports for these issues.<br>
<br>
</div></div>This one should already be fixed in master. If it isn&#39;t, definitely file a new one!<br>
<br>
-Joe<br>
<div class="HOEnZb"><div class="h5">______________________________<wbr>_________________<br>
swift-evolution mailing list<br>
<a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a><br>
<a href="https://lists.swift.org/mailman/listinfo/swift-evolution" rel="noreferrer" target="_blank">https://lists.swift.org/<wbr>mailman/listinfo/swift-<wbr>evolution</a><br>
</div></div></blockquote></div><br><br clear="all"><div><br></div>-- <br><div class="gmail_signature" data-smartmail="gmail_signature">Chris Eidhof</div>
</div>