<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class="">Another example of the compiler being not so helpful:<div class=""><br class=""></div><div class="">func f(completion: (()->())? = nil) {<br class=""><span class="Apple-tab-span" style="white-space:pre">        </span>completion()<br class="">}</div><div class=""><br class=""></div><div class="">The compiler offers to insert a ! after `completion`, which is a strictly worse choice than inserting a ?.</div><div class=""><br class=""><div><blockquote type="cite" class=""><div class="">On Jul 15, 2017, at 7:48 AM, Rod Brown <<a href="mailto:rodney.brown6@icloud.com" class="">rodney.brown6@icloud.com</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div style="font-family: Helvetica; font-size: 13px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><blockquote type="cite" class=""><div class=""><br class="Apple-interchange-newline">On 15 Jul 2017, at 9:54 am, Robert Bennett via swift-evolution <<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div dir="auto" class=""><div class=""></div><div class="">For expressions whose type is definitely non-optional, it makes sense to verbally suggest both ! and ?? (and/or !! – was that accepted?), and it’s probably best to insert ! when the fixit is accepted. For expressions whose type is undetermined, but which need some form of Optional handling, it would be best for the compiler to assume the type is meant to be optional and insert a ?.</div></div></div></blockquote><div class=""><br class=""></div><div class="">I think its fair that where the context can be optional, the default fixit should be optional. I’ve seen this issue myself from junior swift devs where they apply a fixit.</div><div class=""><br class=""></div><div class="">e.g.:</div><div class=""><br class=""></div><div class=""><font face="Menlo" class="">let optionalReturnedValue = item.optionalValue.optionalValue2?.item</font></div><div class=""><br class=""></div><div class="">And the fixit Xcode recommends on optionalValue is “!"…</div><div class=""><br class=""></div><div class=""><font face="Menlo" class="">let optionalReturnedValue = item.optionalValue!.optionalValue2?.item</font></div><div class=""><br class=""></div><div class="">It seems wiser in these cases if the compiler is smart enough for the default fixit to be “?”. I’m not sure if the compiler is able to do that or is in scope, that’s for smarter people than I to say.</div><div class=""><br class=""></div><div class="">In cases where the compiler, due to the context, requires the value to be non-optional, for a “!”, “??”, or the proposed “!!” makes sense.</div><div class=""><br class=""></div><div class="">“If let”, “guard let” etc all very much butcher the code at the callsite. They fundamentally change the control flow, and I could imagine many of the times its suggestions really won’t make sense for the given situation. How smart should we make the compiler before we’re practically making it rewrite all your code anyway? In this case, I’d rather there be no fixit at all, and just let the developer actually understand and restructure their code to correctly handle the optional case.</div><div class=""><br class=""></div><div class="">- Rod</div><div class=""><br class=""></div></div><div style="font-family: Helvetica; font-size: 13px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><br class=""><blockquote type="cite" class=""><div class=""><div dir="auto" class=""><div class=""><br class="">On Jul 14, 2017, at 2:41 PM, Erica Sadun via swift-evolution <<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>> wrote:<br class=""><br class=""></div><blockquote type="cite" class=""><div class=""><div class=""><br class=""></div><div class=""><blockquote type="cite" class=""><div class="">On Jul 14, 2017, at 2:11 AM, Víctor Pimentel via swift-evolution <<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div class=""><blockquote type="cite" class="" style="font-family: Palatino-Roman; font-size: 14px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;">On 14 Jul 2017, at 08:05, Rod Brown via swift-evolution <<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>> wrote:<br class=""><br class=""><br class=""><br class=""><blockquote type="cite" class="">On 14 Jul 2017, at 2:36 pm, Robert Bennett via swift-evolution <<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>> wrote:<br class=""><br class="">When writing Swift code, it is not uncommon to forget to unwrap optionals. The compiler will offer a fixit, telling you you must insert either a ? or a !. However, when you accept the fixit, ! is inserted (at least, it is for me in Xcode 8.3).<br class=""></blockquote>When you treat an optional as non-optional, the compiler has no way to do a fixit that would appropriately handle the optional. Felix made a good example. The only direct fixit would be a force unwrap. If you used “?” then your non-optional use would turn into an optional and your parameter would generally be non-optional. The fixit is just explicitly doing what you implicitly expected it to do.<br class=""><br class=""><blockquote type="cite" class=""><br class="">Ideally the fixit would default to ? because this is the preferred option; ! is often a sign of non-Swifty code and does not interact well with idiomatic Swift constructs such as if-let-(as?), guard-let-(as?)-else, etc. Also I think it’s safe to say that fixits should not err on the side of crashing at runtime.<br class=""></blockquote><br class="">" ! is often a sign of non-Swifty code “<br class="">I would strongly challenge this assumption. Many core team members have commented about appropriate uses of the ! operator. It shouldn’t be used lightly, but it’s there for a reason and it most definitely isn’t “non-swifty”.<br class=""></blockquote><br class="" style="font-family: Palatino-Roman; font-size: 14px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;"><span class="" style="font-family: Palatino-Roman; font-size: 14px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;">I think it's not a farfetched assumption to imply that if the compiler encounters that code, the programmer didn't realize or remember that they were dealing with optionals.</span><br class="" style="font-family: Palatino-Roman; font-size: 14px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;"><br class="" style="font-family: Palatino-Roman; font-size: 14px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;"><span class="" style="font-family: Palatino-Roman; font-size: 14px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;">If the compiler suggests to force unwrap that expression, it is also fair to assume that most inexperience programmers will just apply that fix it. A more experience programmer can decide whether to force unwrap it or to handle the nil case in any other way, depending on the context and code style.</span><br class="" style="font-family: Palatino-Roman; font-size: 14px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;"><br class="" style="font-family: Palatino-Roman; font-size: 14px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;"><span class="" style="font-family: Palatino-Roman; font-size: 14px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;">Personally, I'd prefer that the compiler didn't encourage so much to use force unwrapping, not because I think that it has no use, but because I think that newbies should not learn that pattern first.</span><br class="" style="font-family: Palatino-Roman; font-size: 14px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;"><br class="" style="font-family: Palatino-Roman; font-size: 14px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;"><span class="" style="font-family: Palatino-Roman; font-size: 14px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;">Surely, if I were new to the language and the compiler kept doing that fix it, I would think that it's "the way" to deal with optionals.</span><br class="" style="font-family: Palatino-Roman; font-size: 14px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;"><br class="" style="font-family: Palatino-Roman; font-size: 14px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;"><span class="" style="font-family: Palatino-Roman; font-size: 14px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;">What would I prefer? At least, for the fix it to provide several options, more or less in this order:</span><br class="" style="font-family: Palatino-Roman; font-size: 14px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;"><br class="" style="font-family: Palatino-Roman; font-size: 14px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;"><span class="" style="font-family: Palatino-Roman; font-size: 14px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;">- checked unwrap (if applies)</span><br class="" style="font-family: Palatino-Roman; font-size: 14px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;"><span class="" style="font-family: Palatino-Roman; font-size: 14px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;">- if let</span><br class="" style="font-family: Palatino-Roman; font-size: 14px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;"><span class="" style="font-family: Palatino-Roman; font-size: 14px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;">- guard let</span><br class="" style="font-family: Palatino-Roman; font-size: 14px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;"><span class="" style="font-family: Palatino-Roman; font-size: 14px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;">- force unwrap</span><br class="" style="font-family: Palatino-Roman; font-size: 14px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;"></div></div></blockquote></div><br class=""><div class=""><div class="">Unfortunately, I think `!` *is* the proper fix-it here. The mechanisms to insert conditional binding, for example, are too unwieldy a tool at the many arbitrary places where an optional is used in place of a non-optional. I believe introducing an unwrap-or-die operator in parens (see <a href="https://github.com/apple/swift-evolution/pull/729" class="">https://github.com/apple/swift-evolution/pull/729</a>) would provide a better fixit:</div><div class=""><br class=""></div><div class="">* A sophisticated developer is unlikely to use fix-its as a blunt instrument to make code work. Their use of `!` can be appropriate and, in their hands, unlikely to be fixit-driven.</div><div class=""><br class=""></div><div class="">* The unsophisticated developer is better served with `!!`, which self-documents the safety issue and can be further evaluated for refactoring, supporting safer learner patterns. Unlike the other approaches for conditional binding, `!!` is fix-it friendly. </div></div><div class=""><br class=""></div><div class="">-- E</div><div class=""><br class=""></div></div></blockquote><blockquote type="cite" class=""><div class=""><span class="">_______________________________________________</span><br class=""><span class="">swift-evolution mailing list</span><br class=""><span class=""><a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a></span><br class=""><span class=""><a href="https://lists.swift.org/mailman/listinfo/swift-evolution" class="">https://lists.swift.org/mailman/listinfo/swift-evolution</a></span><br class=""></div></blockquote></div>_______________________________________________<br class="">swift-evolution mailing list<br class=""><a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a><br class=""><a href="https://lists.swift.org/mailman/listinfo/swift-evolution" class="">https://lists.swift.org/mailman/listinfo/swift-evolution</a></div></blockquote></div></div></blockquote></div><br class=""></div></body></html>