<div dir="ltr">I&#39;ve thought of this before, too, and I agree that it&#39;s light enough it could probably replace implicit promotion. That said, I&#39;m not convinced we&#39;d really want to remove implicit promotion everywhere.<div><br></div><div>I&#39;d also be concerned that &quot;postfix ?&quot; is becoming too overloaded — it&#39;s already used in optional chaining (where it sort of &quot;removes&quot; a layer of optionality), and it&#39;s the &quot;optional pattern&quot; for case statements...this idea would see it used with non-optional values being passed to optional parameters, and there&#39;s another thread started recently which (although it seems unlikely to happen in the near future) would see it used with optional values being passed to non-optional parameters. &quot;postfix ?&quot; just becomes the &quot;solve all my problems&quot; operator, and I&#39;m pretty sure readability would suffer for it.</div><div class="gmail_extra"><br clear="all"><div><div class="gmail_signature" data-smartmail="gmail_signature"><div dir="ltr"><div>Jacob<br></div></div></div></div>
<br><div class="gmail_quote">On Tue, Jul 12, 2016 at 8:33 AM, Nevin Brackett-Rozinsky 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 dir="ltr">Regarding the spelling of optional promotion, I think “postfix ?” could be a solution. Notably, it already works in pattern matching (see the first two case conditions here):<div><br><div><div>let anInt = 16</div><div>let anOpt = Optional(anInt)</div><div><br></div><div>switch anOpt {</div><div>case 2? : print(&quot;Deuces&quot;)</div><div>case anInt? : print(&quot;Huzzah&quot;)</div><div>default : print(&quot;Eh&quot;)</div><div>}</div><div><br></div><div>I propose we make ”postfix ?” be a general-purpose optionalizing operator, which lets you write:</div><div><br></div><div>let anOpt = anInt?      // Optional&lt;Int&gt;.some(anInt)</div><div>let anotherOpt = 2?     // Optional&lt;Int&gt;.some(2)</div><div><br></div><div>Notably “?” would be essentially the inverse of “!”, so given the above we would have:</div><div><br></div><div>anInt == anOpt!</div><div>2 == anotherOpt!</div><div><br></div><div>If we could write it ourselves the implementation would be simply,</div><div><br></div><div>postfix operator ? {}</div><div>postfix func ? &lt;T&gt; (value: T) -&gt; T? { return Optional(value) }</div><div><br></div><div>The “?” syntax is so light that we could seriously consider removing all implicit promotion to optionals, and just use “?”. Thus:</div><div><br></div><div>func takesOptionalInt(_ x: Int?) { }</div><div><br></div><div>takesOptionalInt(2?)<br></div><div>takesOptionalInt(anInt?)</div><div>takesOptionalInt(anOpt)</div><div><br></div><div>In general, anytime you have a value that you want to promote to an optional, you would just put a “?” after it.</div><div><br></div><div>The one place I see where ambiguity can arise is optional chaining. I think “anOpt?.someMethodOnInt()” should use optional chaining, whereas explicit promotion followed by member access would need parentheses: “(anOpt?).someMethodOnDoubleOptional()”.</div><div><br></div><div>In particular, “anInt?.something()” should probably be a syntax error (attempting to using optional chaining on non-optional value), it should not silently become “(anInt?).something()” — that would have to use parentheses.</div><div><br></div><div>Anyway, that’s my idea: “postfix ?” for general-purpose optional wrapping.</div><div><br></div><div>Is this worthy of consideration?</div><div>Should it be part of the current proposal or spun off separately?</div><div>Would “postfix ?” sufficiently soften the landing to enable the elimination of implicit optional-promotion across the board?</div><div>And is there a better way to handle its interaction with optional chaining?</div><div><br></div><div>Thanks,</div><div>Nevin</div><div><br></div><div><br></div></div></div></div><div class="HOEnZb"><div class="h5"><div class="gmail_extra"><br><div class="gmail_quote">On Tue, Jul 12, 2016 at 3:58 AM, Charlie Monroe 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">An example to keep in mind:<div><br></div><div>let dict: [String : String] = ...</div><div>if dict[&quot;key&quot;] == &quot;value&quot; { // String? == String</div><div><span style="white-space:pre-wrap">        </span>// Do something</div><div>}</div><div><br></div><div>If I understand correctly, when the proposal is accepted, you&#39;d need to do something like:</div><div><br></div><div>if let value = dict[&quot;key&quot;], value == &quot;value&quot; { } </div><div>-- OR --</div><div>if dict[&quot;key&quot;] == Optional(&quot;value&quot;) { }</div><div><br></div><div>It&#39;s not an end of the world, but makes life a bit more difficult and such usecase should be kept in mind.</div><div><div><div><br></div><div><br><div><blockquote type="cite"><div>On Jul 12, 2016, at 9:09 AM, Mark Lacey via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>&gt; wrote:</div><br><div><div style="word-wrap:break-word"><br><div><blockquote type="cite"><div>On Jul 11, 2016, at 11:55 PM, Jacob Bandes-Storch &lt;<a href="mailto:jtbandes@gmail.com" target="_blank">jtbandes@gmail.com</a>&gt; wrote:</div><br><div><div dir="ltr">Mark,<div>Thanks for writing this up. Just to clarify, will these still work if your proposal is implemented?</div><div><br></div><div>    let x: Int?</div><div>    let y: Int</div><div>    struct NotEquatable {}<br></div><div>    let z: NotEquatable?</div><div><br></div><div>    x == y; x != y</div><div>    x == nil; x != nil</div><div>    z == nil; z != nil</div><div class="gmail_extra"><br></div><div class="gmail_extra">I would hope that these continue to work. If any changes need to be made to ensure that, please make sure they&#39;re included in the proposal too.</div></div></div></blockquote><div><br></div>The last four would work, but the first two (x == y and x != y) would not because they still involve coercing y to an optional.</div><div><br></div><div>Similarly, === and !== on reference types where one is an optional would require coercing one side, and would not be accepted without an explicit cast using Optional().</div><div><br></div><div>I’m curious what the motivation is for further special casing these operators. They do occur more in practice than &lt;, &lt;=, &gt;, &gt;= (in fact most of the source updates I had to make were due to === and !==, with == and != a close second), but overall these are still quite uncommon from what I’ve seen.</div><div><br></div><div>If you’d like I can certainly update the “alternatives considered” to include the suggestion that we add overloads for (T, T?) and (T?, T) for those four operators.</div><div><br></div><div>Mark</div><div><br><blockquote type="cite"><div><div dir="ltr"><div class="gmail_extra"><br clear="all"><div><div data-smartmail="gmail_signature"><div dir="ltr"><div>Jacob<br></div></div></div></div>
<br><div class="gmail_quote">On Mon, Jul 11, 2016 at 9:35 PM, Mark Lacey <span dir="ltr">&lt;<a href="mailto:mark.lacey@apple.com" target="_blank">mark.lacey@apple.com</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div style="word-wrap:break-word"><br><div><div><div><blockquote type="cite"><div>On Jul 11, 2016, at 9:12 PM, Chris Lattner via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>&gt; wrote:</div><br><div><div style="word-wrap:break-word"><br><div><blockquote type="cite"><div>On Jul 11, 2016, at 8:14 PM, Jacob Bandes-Storch via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>&gt; wrote:</div><br><div><div dir="ltr"><div>You&#39;d have to unwrap it, or use the ??/==/!= operators: <a href="https://gist.github.com/jtbandes/9d88cc83ceceb6c62f38" target="_blank">https://gist.github.com/jtbandes/9d88cc83ceceb6c62f38</a></div><div><br></div><div>I&#39;d be okay with &lt;/&lt;=/&gt;/&gt;= returning Bool?, as I suggested in an older email (which somehow didn&#39;t make it to gmane&#39;s archive, but it&#39;s quoted in <a href="http://thread.gmane.org/gmane.comp.lang.swift.evolution/10095" target="_blank">some other messages</a>). I think it would be more convenient in some cases than unwrapping the individual values before comparing them.</div></div></div></blockquote><br></div><div>I’d be strongly opposed to those operator returning “Bool?”.  Doing so would prevent conforming to Comparable and would be extremely surprising.</div><div><br></div><div>-Chris</div></div></div></blockquote><div><br></div></div></div>I just pushed the current draft of the proposal: <a href="https://github.com/rudkx/swift-evolution/blob/eliminate-value-to-optional-coercion/proposals/0000-disallow-value-to-optional-coercion-in-operator-arguments.md" target="_blank">https://github.com/rudkx/swift-evolution/blob/eliminate-value-to-optional-coercion/proposals/0000-disallow-value-to-optional-coercion-in-operator-arguments.md</a></div><div><br></div><div>I haven’t addressed removal of the ordered comparison operators. I suspect this should be a separate proposal, but I can roll that into this one if it’s desired.</div><div><br></div><div>I’ll update the proposal as the discussion continues until it’s selected for review.</div><span><font color="#888888"><div><br></div><div>Mark</div></font></span><span><div><br></div><div><blockquote type="cite"><div><div style="word-wrap:break-word"><br></div>_______________________________________________<br>swift-evolution mailing list<br><a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a><br><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><br></span></div></blockquote></div><br></div></div>
</div></blockquote></div><br></div>_______________________________________________<br>swift-evolution mailing list<br><a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a><br><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><br></div></div></div></div><br>_______________________________________________<br>
swift-evolution mailing list<br>
<a href="mailto:swift-evolution@swift.org" target="_blank">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>
</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></div>