<html><head><meta http-equiv="content-type" content="text/html; charset=utf-8"></head><body dir="auto"><div><div style="direction: inherit;"><span style="background-color: rgba(255, 255, 255, 0);">Under our proposal you can return to the old semantics of printing nil with an explicit optional cast - one which we will offer to insert for you.</span></div><div style="direction: inherit;"><span style="background-color: rgba(255, 255, 255, 0);"><br></span></div><div style="direction: inherit;"><span style="background-color: rgba(255, 255, 255, 0);">Otherwise if you actually intend for a default value that value would have type Int, not String. &nbsp;Under the current regime if you want to print something custom the for nil the way you've got it now you're going to have to go through the reflecting initializer anyway so I don't see a problem here.</span></div><div style="direction: inherit;"><br></div>~Robert Widmann</div><div><br>2016/10/03 19:25、Charlie Monroe via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a>&gt; のメッセージ:<br><br></div><blockquote type="cite"><div><meta http-equiv="Content-Type" content="text/html charset=us-ascii">I've already suggested this quite some time back and was told that this doesn't need to go through evolution. It's filed here:&nbsp;<a href="https://bugs.swift.org/browse/SR-1882" class="">https://bugs.swift.org/browse/SR-1882</a><div class=""><br class=""></div><div class="">Unfortunately, I haven't had time to look into it myself and I'm unlikely to have the time anytime soon...</div><div class=""><br class=""><div><blockquote type="cite" class=""><div class="">On Oct 3, 2016, at 7:52 PM, Harlan Haskins via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>&gt; wrote:</div><br class="Apple-interchange-newline"><div class=""><meta http-equiv="content-type" content="text/html; charset=utf-8" class=""><div dir="auto" class=""><div class=""><span class=""></span></div><div class=""><div class="">Hey all,</div><div class=""><br class=""></div><div class="">Julio Carrettoni, Robert Widmann, and I have been working on a proposal to mitigate something that's burned us all since Swift 1. We'd love some feedback!</div><div class=""><br class=""></div><div class="">It's available here:&nbsp;<a href="https://gist.github.com/harlanhaskins/63b7343e7fe4e5f4c6cfbe9413a98fdd" class="">https://gist.github.com/harlanhaskins/63b7343e7fe4e5f4c6cfbe9413a98fdd</a></div><div class=""><br class=""></div><div class="">I've posted the current draft below.</div><div class=""><br class=""></div><div class="">Thanks,</div><div class="">Harlan Haskins<br class=""></div><div class=""><br class=""></div><div class=""><h1 style="box-sizing: border-box; margin-right: 0px; margin-bottom: 16px; margin-left: 0px; line-height: 1.25; padding-bottom: 0.3em; border-bottom-width: 1px; border-bottom-style: solid; border-bottom-color: rgb(238, 238, 238); margin-top: 0px !important;" class=""><font size="3" class=""><span style="background-color: rgba(255, 255, 255, 0);" class="">Disallow Optionals in String Interpolation Segments</span></font></h1><ul style="box-sizing: border-box; padding-left: 2em; margin-top: 0px; margin-bottom: 16px;" class=""><li style="box-sizing: border-box;" class=""><span style="background-color: rgba(255, 255, 255, 0);" class="">Proposal:&nbsp;<a href="https://gist.github.com/harlanhaskins/NNNN-filename.md" style="box-sizing: border-box; -webkit-text-decoration-skip: objects; text-decoration: none;" class="">SE-NNNN</a></span></li><li style="box-sizing: border-box; margin-top: 0.25em;" class=""><span style="background-color: rgba(255, 255, 255, 0);" class="">Authors:&nbsp;<a href="https://github.com/harlanhaskins" style="box-sizing: border-box; -webkit-text-decoration-skip: objects; text-decoration: none;" class="">Harlan Haskins</a>,&nbsp;<a href="https://github.com/Julioacarrettoni" style="box-sizing: border-box; -webkit-text-decoration-skip: objects; text-decoration: none;" class="">Julio Carrettoni</a>,&nbsp;<a href="https://github.com/CodaFi" style="box-sizing: border-box; -webkit-text-decoration-skip: objects; text-decoration: none;" class="">Robert Widmann</a></span></li><li style="box-sizing: border-box; margin-top: 0.25em;" class=""><span style="background-color: rgba(255, 255, 255, 0);" class="">Review Manager: TBD</span></li><li style="box-sizing: border-box; margin-top: 0.25em;" class=""><span style="background-color: rgba(255, 255, 255, 0);" class="">Status:&nbsp;<span style="box-sizing: border-box; font-weight: 600;" class="">Awaiting revie</span></span></li></ul><h2 style="box-sizing: border-box; margin-top: 24px; margin-bottom: 16px; line-height: 1.25; padding-bottom: 0.3em; border-bottom-width: 1px; border-bottom-style: solid; border-bottom-color: rgb(238, 238, 238);" class=""><a id="user-content-introduction" class="anchor" href="https://gist.github.com/harlanhaskins/63b7343e7fe4e5f4c6cfbe9413a98fdd#introduction" aria-hidden="true" style="box-sizing: border-box; -webkit-text-decoration-skip: objects; text-decoration: none; float: left; padding-right: 4px; margin-left: -20px; line-height: 1;"><svg aria-hidden="true" class="octicon octicon-link" height="16" version="1.1" viewBox="0 0 16 16" width="16"></svg><font size="3" class=""><span style="background-color: rgba(255, 255, 255, 0);" class=""><path d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z" class=""></path></span></font></a><font size="3" class=""><span style="background-color: rgba(255, 255, 255, 0);" class="">Introduction</span></font></h2><p style="box-sizing: border-box; margin-top: 0px; margin-bottom: 16px;" class=""><span style="background-color: rgba(255, 255, 255, 0);" class="">Swift developers frequently use string interpolation as a convenient, concise syntax for interweaving variable values with strings. The interpolation machinery, however, has surprising behavior in one specific case:&nbsp;<code style="box-sizing: border-box; padding: 0.2em 0px; margin: 0px; border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;" class="">Optional&lt;T&gt;</code>. If a user puts an optional value into a string interpolation segment, it will insert either&nbsp;<code style="box-sizing: border-box; padding: 0.2em 0px; margin: 0px; border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;" class="">"Optional("value")"</code>&nbsp;or&nbsp;<code style="box-sizing: border-box; padding: 0.2em 0px; margin: 0px; border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;" class="">"nil"</code>&nbsp;in the resulting string. Neither of these is particularly desirable, so we propose a warning and fix-it to surface solutions to these potential mistakes.</span></p><p style="box-sizing: border-box; margin-top: 0px; margin-bottom: 16px;" class=""><span style="background-color: rgba(255, 255, 255, 0);" class="">Swift-evolution thread:&nbsp;<a href="https://lists.swift.org/pipermail/swift-evolution/" style="box-sizing: border-box; -webkit-text-decoration-skip: objects; text-decoration: none;" class="">Discussion thread topic for that proposal</a></span></p><h2 style="box-sizing: border-box; margin-top: 24px; margin-bottom: 16px; line-height: 1.25; padding-bottom: 0.3em; border-bottom-width: 1px; border-bottom-style: solid; border-bottom-color: rgb(238, 238, 238);" class=""><a id="user-content-motivation" class="anchor" href="https://gist.github.com/harlanhaskins/63b7343e7fe4e5f4c6cfbe9413a98fdd#motivation" aria-hidden="true" style="box-sizing: border-box; -webkit-text-decoration-skip: objects; text-decoration: none; float: left; padding-right: 4px; margin-left: -20px; line-height: 1;"><svg aria-hidden="true" class="octicon octicon-link" height="16" version="1.1" viewBox="0 0 16 16" width="16"></svg><font size="3" class=""><span style="background-color: rgba(255, 255, 255, 0);" class=""><path d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z" class=""></path></span></font></a><font size="3" class=""><span style="background-color: rgba(255, 255, 255, 0);" class="">Motivation</span></font></h2><p style="box-sizing: border-box; margin-top: 0px; margin-bottom: 16px;" class=""><span style="background-color: rgba(255, 255, 255, 0);" class=""><em style="box-sizing: border-box;" class="">The Swift Programming Language</em>&nbsp;defines string interpolation segments as "a way to construct a new String value from a mix of constants, variables, literals, and expressions". There is one type that runs counter to this definition:&nbsp;<code style="box-sizing: border-box; padding: 0.2em 0px; margin: 0px; border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;" class="">Optional</code>. The&nbsp;<code style="box-sizing: border-box; padding: 0.2em 0px; margin: 0px; border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;" class="">.none</code>&nbsp;case in particular is used to indicate the absence of a value. Moreover, its inclusion in interpolation segments leads to the dreaded&nbsp;<code style="box-sizing: border-box; padding: 0.2em 0px; margin: 0px; border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;" class="">"nil"</code>&nbsp;in output that is often fed to UI elements. Even barring that, interpolating a non-nil optional value yields&nbsp;<code style="box-sizing: border-box; padding: 0.2em 0px; margin: 0px; border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;" class="">"Optional("value")"</code>, a result that is not useful even in logged output.</span></p><p style="box-sizing: border-box; margin-top: 0px; margin-bottom: 16px;" class=""><span style="background-color: rgba(255, 255, 255, 0);" class="">Given that the&nbsp;<code style="box-sizing: border-box; padding: 0.2em 0px; margin: 0px; border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;" class="">Optional</code>&nbsp;type is never fit for display to the end user, and can often be a surprising find in the console, we propose that requesting an&nbsp;<code style="box-sizing: border-box; padding: 0.2em 0px; margin: 0px; border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;" class="">Optional</code>'s debug description be an explicit act. This proposal now requires a warning when using an expression of&nbsp;<code style="box-sizing: border-box; padding: 0.2em 0px; margin: 0px; border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;" class="">Optional</code>&nbsp;type within a string interpolation segment.</span></p><h2 style="box-sizing: border-box; margin-top: 24px; margin-bottom: 16px; line-height: 1.25; padding-bottom: 0.3em; border-bottom-width: 1px; border-bottom-style: solid; border-bottom-color: rgb(238, 238, 238);" class=""><a id="user-content-proposed-solution" class="anchor" href="https://gist.github.com/harlanhaskins/63b7343e7fe4e5f4c6cfbe9413a98fdd#proposed-solution" aria-hidden="true" style="box-sizing: border-box; -webkit-text-decoration-skip: objects; text-decoration: none; float: left; padding-right: 4px; margin-left: -20px; line-height: 1;"><svg aria-hidden="true" class="octicon octicon-link" height="16" version="1.1" viewBox="0 0 16 16" width="16"></svg><font size="3" class=""><span style="background-color: rgba(255, 255, 255, 0);" class=""><path d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z" class=""></path></span></font></a><font size="3" class=""><span style="background-color: rgba(255, 255, 255, 0);" class="">Proposed solution</span></font></h2><p style="box-sizing: border-box; margin-top: 0px; margin-bottom: 16px;" class=""><span style="background-color: rgba(255, 255, 255, 0);" class="">The user will be warned after attempting to use an expression with type&nbsp;<code style="box-sizing: border-box; padding: 0.2em 0px; margin: 0px; border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;" class="">Optional&lt;T&gt;</code>&nbsp;in a string interpolation segment. They will then be offered a fixit suggesting they explicitly request the&nbsp;<code style="box-sizing: border-box; padding: 0.2em 0px; margin: 0px; border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;" class="">debugDescription</code>&nbsp;of the&nbsp;<code style="box-sizing: border-box; padding: 0.2em 0px; margin: 0px; border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;" class="">Optional</code>&nbsp;value instead.</span></p><h2 style="box-sizing: border-box; margin-top: 24px; margin-bottom: 16px; line-height: 1.25; padding-bottom: 0.3em; border-bottom-width: 1px; border-bottom-style: solid; border-bottom-color: rgb(238, 238, 238);" class=""><a id="user-content-detailed-design" class="anchor" href="https://gist.github.com/harlanhaskins/63b7343e7fe4e5f4c6cfbe9413a98fdd#detailed-design" aria-hidden="true" style="box-sizing: border-box; -webkit-text-decoration-skip: objects; text-decoration: none; float: left; padding-right: 4px; margin-left: -20px; line-height: 1;"><svg aria-hidden="true" class="octicon octicon-link" height="16" version="1.1" viewBox="0 0 16 16" width="16"></svg><font size="3" class=""><span style="background-color: rgba(255, 255, 255, 0);" class=""><path d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z" class=""></path></span></font></a><font size="3" class=""><span style="background-color: rgba(255, 255, 255, 0);" class="">Detailed design</span></font></h2><p style="box-sizing: border-box; margin-top: 0px; margin-bottom: 16px;" class=""><span style="background-color: rgba(255, 255, 255, 0);" class="">Semantic analysis currently does not do much but guarantee the well-formedness of expressions in interpolation segments. These are then fed directly to&nbsp;<code style="box-sizing: border-box; padding: 0.2em 0px; margin: 0px; border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;" class="">String.init(stringInterpolationSegment:)</code>&nbsp;and are run through the runtime reflection system to generate a description. Semantic analysis will be tweaked to inspect the result of solving an interpolation segment for an&nbsp;<code style="box-sizing: border-box; padding: 0.2em 0px; margin: 0px; border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;" class="">Optional</code>&nbsp;and will offer a fixit in that case.</span></p><h2 style="box-sizing: border-box; margin-top: 24px; margin-bottom: 16px; line-height: 1.25; padding-bottom: 0.3em; border-bottom-width: 1px; border-bottom-style: solid; border-bottom-color: rgb(238, 238, 238);" class=""><a id="user-content-impact-on-existing-code" class="anchor" href="https://gist.github.com/harlanhaskins/63b7343e7fe4e5f4c6cfbe9413a98fdd#impact-on-existing-code" aria-hidden="true" style="box-sizing: border-box; -webkit-text-decoration-skip: objects; text-decoration: none; float: left; padding-right: 4px; margin-left: -20px; line-height: 1;"><svg aria-hidden="true" class="octicon octicon-link" height="16" version="1.1" viewBox="0 0 16 16" width="16"></svg><font size="3" class=""><span style="background-color: rgba(255, 255, 255, 0);" class=""><path d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z" class=""></path></span></font></a><font size="3" class=""><span style="background-color: rgba(255, 255, 255, 0);" class="">Impact on existing code</span></font></h2><p style="box-sizing: border-box; margin-top: 0px; margin-bottom: 16px;" class=""><span style="background-color: rgba(255, 255, 255, 0);" class="">As this is a warning, code written before this proposal will continue to compile and run with the same semantics as before. Authors of code that makes use of this unsafe pattern will be offered a migration path to the safer, more explicit form.</span></p><h2 style="box-sizing: border-box; margin-top: 24px; margin-bottom: 16px; line-height: 1.25; padding-bottom: 0.3em; border-bottom-width: 1px; border-bottom-style: solid; border-bottom-color: rgb(238, 238, 238);" class=""><a id="user-content-alternatives-considered" class="anchor" href="https://gist.github.com/harlanhaskins/63b7343e7fe4e5f4c6cfbe9413a98fdd#alternatives-considered" aria-hidden="true" style="box-sizing: border-box; -webkit-text-decoration-skip: objects; text-decoration: none; float: left; padding-right: 4px; margin-left: -20px; line-height: 1;"><svg aria-hidden="true" class="octicon octicon-link" height="16" version="1.1" viewBox="0 0 16 16" width="16"></svg><font size="3" class=""><span style="background-color: rgba(255, 255, 255, 0);" class=""><path d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z" class=""></path></span></font></a><font size="3" class=""><span style="background-color: rgba(255, 255, 255, 0);" class="">Alternatives considered</span></font></h2><ul style="box-sizing: border-box; padding-left: 2em; margin-top: 0px; margin-bottom: 0px !important;" class=""><li style="box-sizing: border-box;" class=""><p style="box-sizing: border-box; margin-top: 16px; margin-bottom: 16px;" class=""><span style="background-color: rgba(255, 255, 255, 0);" class="">A fixit that suggests a default value be inserted would be entirely appropriate (following the style of the fixit introduced in&nbsp;<a href="https://github.com/apple/swift-evolution/blob/master/proposals/0140-bridge-optional-to-nsnull.md" style="box-sizing: border-box; -webkit-text-decoration-skip: objects; text-decoration: none;" class="">SE-0140</a>).</span></p></li><li style="box-sizing: border-box; margin-top: 0.25em;" class=""><p style="box-sizing: border-box; margin-top: 16px; margin-bottom: 16px;" class=""><span style="background-color: rgba(255, 255, 255, 0);" class="">Forbidding this pattern by hard error would make this proposal a breaking change that is out of scope for this stage of Swift's development.</span></p></li><li style="box-sizing: border-box; margin-top: 0.25em;" class=""><p style="box-sizing: border-box; margin-top: 16px; margin-bottom: 16px;" class=""><span style="background-color: rgba(255, 255, 255, 0);" class="">A fixit that introduces a force-unwrapping would technically work as well, however it would be fixing a dangerous operation with yet another dangerous operation.</span></p></li></ul></div></div><div class=""><br class=""><br class="">Sent from my iPad</div></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">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br class=""></div></blockquote></div><br class=""></div></div></blockquote><blockquote type="cite"><div><span>_______________________________________________</span><br><span>swift-evolution mailing list</span><br><span><a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a></span><br><span><a href="https://lists.swift.org/mailman/listinfo/swift-evolution">https://lists.swift.org/mailman/listinfo/swift-evolution</a></span><br></div></blockquote></body></html>