<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"><<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>></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 <<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>> 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) -> Value { … }</div><div>}</div></blockquote></div></div></blockquote></div><div><br></div><div>I think it's really a shortcoming in <span style="color:rgb(112,61,170);font-family:Menlo;font-size:11px">Dictionary</span>'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—"upserts", 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>'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"> -> </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: "two"]</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)">"one"</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">"deux"</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: "two", 1: "one"]</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>? -> <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>? -> <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">"Söze"</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">"Kujan"</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">"Kint"</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)">"</span><font color="#d12f1b" face="Menlo" style="font-family:Menlo;font-size:11px">Söze"</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'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)">"</span><span style="color:rgb(209,47,27)">Kint</span><span style="color:rgb(209,47,27)">"</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 == ["Kujan": 1, "Kint": 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>'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'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's no promise that it'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'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">) -> </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">?) -> </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've followed the conversation for a couple of days and read through the proposal quickly. I'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>