<div dir="ltr">I've thought of this before, too, and I agree that it's light enough it could probably replace implicit promotion. That said, I'm not convinced we'd really want to remove implicit promotion everywhere.<div><br></div><div>I'd also be concerned that "postfix ?" is becoming too overloaded — it's already used in optional chaining (where it sort of "removes" a layer of optionality), and it's the "optional pattern" for case statements...this idea would see it used with non-optional values being passed to optional parameters, and there'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. "postfix ?" just becomes the "solve all my problems" operator, and I'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"><<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 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("Deuces")</div><div>case anInt? : print("Huzzah")</div><div>default : print("Eh")</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<Int>.some(anInt)</div><div>let anotherOpt = 2? // Optional<Int>.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 ? <T> (value: T) -> 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"><<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">An example to keep in mind:<div><br></div><div>let dict: [String : String] = ...</div><div>if dict["key"] == "value" { // 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'd need to do something like:</div><div><br></div><div>if let value = dict["key"], value == "value" { } </div><div>-- OR --</div><div>if dict["key"] == Optional("value") { }</div><div><br></div><div>It'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 <<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>> 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 <<a href="mailto:jtbandes@gmail.com" target="_blank">jtbandes@gmail.com</a>> 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'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 <, <=, >, >= (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"><<a href="mailto:mark.lacey@apple.com" target="_blank">mark.lacey@apple.com</a>></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 <<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>> 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 <<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>> wrote:</div><br><div><div dir="ltr"><div>You'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'd be okay with </<=/>/>= returning Bool?, as I suggested in an older email (which somehow didn't make it to gmane's archive, but it'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>