<div dir="ltr">You could argue that rewrap is just flatMap </div><div class="gmail_extra"><br clear="all"><div><div class="gmail_signature"><div dir="ltr"><div><div dir="ltr"><div><div dir="ltr">







<p><b><font color="#cc0000">___________________________________</font></b></p><p><b>James⎥Head of Awesome</b></p><p><b><font color="#cc0000"><a href="mailto:james@supmenow.com" target="_blank">james@supmenow.com</a>⎥<a href="http://supmenow.com" target="_blank">supmenow.com</a></font></b></p><p><b><font size="2">Sup</font></b></p><p><b><font size="2">Runway East
</font></b></p><p><b><font size="2">10 Finsbury Square</font></b></p><p><b><font size="2">London</font></b></p><p><b><font size="2">
EC2A 1AF </font></b></p></div></div></div></div></div></div></div>
<br><div class="gmail_quote">On Tue, Feb 16, 2016 at 7:44 PM, Pyry Jahkola 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 style="word-wrap:break-word"><div>Below is my -1 on the proposal. But before that:</div><div><br><blockquote type="cite"><span class=""><div>On 16 Feb 2016, at 20:26, Joe Groff via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>&gt; wrote:</div><br></span><div><div style="word-wrap:break-word"><span class=""><div>I think a more expressive alternative approach to this problem would be to extend Dictionary with a `subscript(_:orDefault:)` member:</div><div><br></div></span><blockquote style="margin:0 0 0 40px;border:none;padding:0px"><div>extension Dictionary {</div><div>  subscript(key: Key, orDefault value: Value) -&gt; Value { … }</div><div>}</div></blockquote></div></div></blockquote></div><div><br></div><div>I think it&#39;s really a shortcoming in <span style="color:rgb(112,61,170);font-family:Menlo;font-size:11px">Dictionary</span>&#39;s interface, where the general use case of updating a key in place usually asks for a lot of boilerplate. Thinking outside the box somewhat, one way to make all kinds of updates—&quot;upserts&quot;, accumulating the value, but also removals—possible would be to extend <span style="color:rgb(112,61,170);font-family:Menlo;font-size:11px">Optional</span>&#39;s interface with this simple addition:</div><div><br></div><div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(187,44,162)">extension<span style="color:#000000"> </span><span style="color:#703daa">Optional</span><span style="color:#000000"> {</span></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(187,44,162)"><span style="color:#000000">    </span>public<span style="color:#000000"> </span>mutating<span style="color:#000000"> </span>func<span style="color:#000000"> rewrap(</span>@noescape<span style="color:#000000"> transform: </span><span style="color:#4f8187">Wrapped</span><span style="color:#000000">? </span>throws<span style="color:#000000"> -&gt; </span><span style="color:#4f8187">Wrapped</span><span style="color:#000000">?) </span>rethrows<span style="color:#000000"> {</span></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo">        <span style="color:#bb2ca2">self</span> = <span style="color:#bb2ca2">try</span> transform(<span style="color:#bb2ca2">self</span>)</div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo">    }</div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo">}</div></div><div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><br></div></div><div>Conditionally inserting a key would then be:</div><div><br></div><div><div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span style="color:rgb(187,44,162)">var</span> dict = [2: &quot;two&quot;]</div></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span style="color:rgb(79,129,135)">dict</span>[<span style="color:rgb(39,42,216)">1</span>].<span style="color:rgb(49,89,93)">rewrap</span> {$0 ?? <span style="color:rgb(209,47,27)">&quot;one&quot;</span>}</div></div><div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><div style="margin:0px;line-height:normal"><span style="color:#4f8187">dict</span>[<span style="color:#272ad8">2</span>].<span style="color:rgb(49,89,93)">rewrap</span> {$0 ?? <span style="color:#d12f1b">&quot;deux&quot;</span>} <span style="color:#008400">// no-op</span></div><div style="margin:0px;line-height:normal"><div style="margin:0px;line-height:normal;color:rgb(0,132,0)">// dict == [2: &quot;two&quot;, 1: &quot;one&quot;]</div></div><div><br></div></div></div><div>Maintaining a set of counters:</div><div><br></div><div><div style="margin:0px;line-height:normal"><div style="font-family:Menlo;font-size:11px;margin:0px;line-height:normal"><span style="color:#bb2ca2">var</span> counts = [<span style="color:#703daa">String</span>: <span style="color:#703daa">Int</span>]()</div><div style="font-family:Menlo;font-size:11px;margin:0px;line-height:normal"><span style="color:#bb2ca2">let</span> increment: <span style="color:#703daa">Int</span>? -&gt; <span style="color:#703daa">Int</span>? = {($0 ?? <span style="color:#272ad8">0</span>) + <span style="color:#272ad8">1</span>}</div><div style="font-family:Menlo;font-size:11px;margin:0px;line-height:normal"><span style="color:#bb2ca2">let</span> decrement: <span style="color:#703daa">Int</span>? -&gt; <span style="color:#703daa">Int</span>? = {</div><div style="font-family:Menlo;font-size:11px;margin:0px;line-height:normal">    <span style="color:#bb2ca2">let</span> n = ($0 ?? <span style="color:#272ad8">0</span>) - <span style="color:#272ad8">1</span></div><div style="font-family:Menlo;font-size:11px;margin:0px;line-height:normal">    <span style="color:#bb2ca2">return</span> n == <span style="color:#272ad8">0</span> ? <span style="color:#bb2ca2">nil</span> : n</div><div style="font-family:Menlo;font-size:11px;margin:0px;line-height:normal">}</div><div style="margin:0px;line-height:normal"><font color="#4f8187" face="Menlo"><span style="font-size:11px">counts</span></font><span style="font-family:Menlo;font-size:11px">[</span><font color="#d12f1b" face="Menlo"><span style="font-size:11px">&quot;Söze&quot;</span></font><span style="font-family:Menlo;font-size:11px">].</span><span style="color:rgb(49,89,93);font-family:Menlo;font-size:11px">rewrap</span><span style="font-family:Menlo;font-size:11px">(</span><font color="#4f8187" face="Menlo"><span style="font-size:11px">increment</span></font><span style="font-family:Menlo;font-size:11px">)</span></div><div style="font-family:Menlo;font-size:11px;margin:0px;line-height:normal;color:rgb(79,129,135)">counts<span style="color:#000000">[</span><span style="color:#d12f1b">&quot;Kujan&quot;</span><span style="color:#000000">].</span><span style="color:rgb(49,89,93)">rewrap</span><span style="color:#000000">(</span>increment<span style="color:#000000">)</span></div><div style="font-family:Menlo;font-size:11px;margin:0px;line-height:normal;color:rgb(79,129,135)">counts<span style="color:#000000">[</span><span style="color:#d12f1b">&quot;Kint&quot;</span><span style="color:#000000">].</span><span style="color:rgb(49,89,93)">rewrap</span><span style="color:#000000">(</span>increment<span style="color:#000000">)</span></div><div style="margin:0px;line-height:normal"><font color="#4f8187" face="Menlo" style="color:rgb(79,129,135);font-family:Menlo;font-size:11px">counts</font><span style="font-family:Menlo;font-size:11px">[</span><span style="font-family:Menlo;font-size:11px;color:rgb(209,47,27)">&quot;</span><font color="#d12f1b" face="Menlo" style="font-family:Menlo;font-size:11px">Söze&quot;</font><span style="font-family:Menlo;font-size:11px">].</span><span style="font-family:Menlo;font-size:11px;color:rgb(49,89,93)">rewrap</span><span style="font-family:Menlo;font-size:11px">(</span><font color="#4f8187" face="Menlo" style="color:rgb(79,129,135);font-family:Menlo;font-size:11px">decrement</font><span style="font-family:Menlo;font-size:11px">) </span><span style="font-family:Menlo;font-size:11px;color:rgb(0,132,0)">//</span><span style="font-family:Menlo;font-size:11px;color:rgb(0,132,0)"> poof… he&#39;s gone</span></div><div style="font-family:Menlo;font-size:11px;margin:0px;line-height:normal;color:rgb(79,129,135)">counts<span style="color:rgb(0,0,0)">[</span><span style="color:rgb(209,47,27)">&quot;</span><span style="color:rgb(209,47,27)">Kint</span><span style="color:rgb(209,47,27)">&quot;</span><span style="color:rgb(0,0,0)">].</span><span style="color:rgb(49,89,93)">rewrap</span><span style="color:rgb(0,0,0)">(</span>increment<span style="color:rgb(0,0,0)">)</span></div><div style="font-family:Menlo;font-size:11px;margin:0px;line-height:normal;color:rgb(0,132,0)">// counts == [&quot;Kujan&quot;: 1, &quot;Kint&quot;: 2]</div><div style="font-family:Menlo;font-size:11px"><br></div><div>Originally I thought calling it simply <span style="color:rgb(49,89,93);font-family:Menlo;font-size:11px">update</span>, however <span style="color:rgb(49,89,93);font-family:Menlo;font-size:11px">rewrap</span> has a closer correspondence to <span style="color:rgb(112,61,170);font-family:Menlo;font-size:11px">Optional</span>&#39;s <span style="color:rgb(79,129,135);font-family:Menlo;font-size:11px">Wrapped</span>, and might thus be less ambiguous.</div><div><br></div><div>— — —</div><div><br></div><div>What comes to the proposal then…</div><div style="font-family:Menlo;font-size:11px"><br></div></div></div><div><div><span class=""><blockquote type="cite">What is your evaluation of the proposal?<br></blockquote><div><br></div></span>-1.<br><br></div><span class=""><div><blockquote type="cite">Is the problem being addressed significant enough to warrant a change to Swift?<br></blockquote><br></div></span><div>I don&#39;t think this is the problem to be addressed. The issue here is that even after the update, the result is still an optional, so there&#39;s no promise that it&#39;ll have a non-<span style="color:rgb(187,44,162);font-family:Menlo;font-size:11px">nil</span> value. I have a feeling <span style="color:rgb(187,44,162);font-family:Menlo;font-size:11px">guard</span> could be used in most of these use cases for a better design. And lazy loading or set-once properties might help a bit too.</div><span class=""><div><br></div><div><blockquote type="cite">Does this proposal fit well with the feel and direction of Swift?<br></blockquote><br></div></span><div>It&#39;s true that we have the in-place mutating <span style="font-family:Menlo;font-size:11px">op=</span> variant of many operators <span style="font-family:Menlo;font-size:11px">op</span> which happen to return the same type as their first argument. However, I see <span style="font-family:Menlo;font-size:11px">??</span> as two overloads (<span style="font-family:Menlo;font-size:11px">(</span><span style="font-family:Menlo;font-size:11px;color:rgb(79,129,135)">T</span><span style="font-family:Menlo;font-size:11px">?, </span><span style="font-family:Menlo;font-size:11px;color:rgb(79,129,135)">T</span><span style="font-family:Menlo;font-size:11px">) -&gt; </span><span style="font-family:Menlo;font-size:11px;color:rgb(79,129,135)">T</span> and <span style="font-family:Menlo;font-size:11px">(</span><span style="font-family:Menlo;font-size:11px;color:rgb(79,129,135)">T</span><span style="font-family:Menlo;font-size:11px">?, </span><span style="font-family:Menlo;font-size:11px;color:rgb(79,129,135)">T</span><span style="font-family:Menlo;font-size:11px">?) -&gt; </span><span style="font-family:Menlo;font-size:11px;color:rgb(79,129,135)">T</span><span style="font-family:Menlo;font-size:11px">?</span>), the one returning non-optional being the more official one which is somewhat against the current practice.</div><div><br></div><div>I also feel the use of this operator would leave too many <span style="color:rgb(79,129,135);font-family:Menlo;font-size:11px">T</span><span style="font-family:Menlo;font-size:11px">?</span> hanging around where <span style="color:rgb(79,129,135);font-family:Menlo;font-size:11px">T</span> would do.</div><span class=""><div><br></div><div><blockquote type="cite">If you have used other languages or libraries with a similar feature, how do you feel that this proposal compares to those?<br></blockquote><br></div></span><div>Ruby comes in mind. Ruby is different in that it does nothing to prevent the Billion Dollar Mistake that they coincidentally call <span style="color:rgb(187,44,162);font-family:Menlo;font-size:11px">nil</span>.</div><span class=""><div><br></div><div><blockquote type="cite">How much effort did you put into your review? A glance, a quick reading, or an in-depth study?</blockquote></div></span></div><div><br></div><div>I&#39;ve followed the conversation for a couple of days and read through the proposal quickly. I&#39;ve thought about the problem domain a lot before though.</div><div><br></div><div><span style="border-collapse:separate;line-height:normal;border-spacing:0px"><div style="word-wrap:break-word"><span style="border-collapse:separate;color:rgb(0,0,0);font-variant:normal;letter-spacing:normal;line-height:normal;text-align:-webkit-auto;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;border-spacing:0px;font-size:12px"><div style="word-wrap:break-word">— Pyry Jahkola</div></span></div></span></div></div><br>_______________________________________________<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/mailman/listinfo/swift-evolution</a><br>
<br></blockquote></div><br></div>