<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=""><br class=""><div><blockquote type="cite" class=""><div class="">On Oct 28, 2016, at 6:22 PM, Erica Sadun via swift-evolution <<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>> wrote:</div><div class=""><div style="font-family: Palatino-Roman; font-size: 14px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><blockquote type="cite" class=""><div class="">On Oct 28, 2016, at 5:55 PM, Kevin Nattinger <<a href="mailto:swift@nattinger.net" class="">swift@nattinger.net</a>> wrote:</div><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; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;"><div class="">On Oct 28, 2016, at 4:45 PM, Erica Sadun via swift-evolution <<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>> wrote:</div><div class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><div class=""><blockquote type="cite" class=""><div class="">On Oct 28, 2016, at 5:00 PM, Huon Wilson <<a href="mailto:huon@apple.com" class="">huon@apple.com</a>> wrote:</div><div class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><div class=""><blockquote type="cite" class=""><div class="">On Oct 28, 2016, at 15:34, Erica Sadun via swift-evolution <<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>> wrote:</div></blockquote><div class="">How does the compiler decide whether to succeed on anycase or succeed on anothercase respectively? In general, the compiler only statically knows that first & second are of type TypeName, not anything about which case (they could be passed in as function parameters, or returned by an opaque function e.g. `let x = OtherLibrary.returnsTypeName(); guard unwrap x else { … }`), and thus the variant to unwrap has to be chosen based only on that piece of information.</div><br class=""></div>It seems to me that doing this either has to be restricted to enums with an “obvious” choice for unwrapping, like Optional, or rely on a sort of forward-looking type inference that Swift doesn’t currently use to deduce the unwrapped type based on how the value is used later (and I’m not sure that works in all cases, e.g. what if T == U for the TypeName example).</div></div></blockquote><br class=""></div><div class="">It succeeds on any one-item case and fails on any non-item case.</div></div></div></blockquote><div class="" style="font-family: Palatino-Roman; font-size: 14px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;"><br class=""></div><div class="" style="font-family: Palatino-Roman; font-size: 14px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;">I think he meant this:</div><div class="" style="font-family: Palatino-Roman; font-size: 14px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;"><br class=""></div><div class="" style="font-family: Palatino-Roman; font-size: 14px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;"><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;"><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(187, 44, 162);">enum</span><span class="" style="font-variant-ligatures: no-common-ligatures;"><span class="Apple-converted-space"> </span>TypeName<T, U> {<span class="Apple-converted-space"> </span></span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(187, 44, 162);">case</span><span class="" style="font-variant-ligatures: no-common-ligatures;"><span class="Apple-converted-space"> </span>anycase(</span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(79, 129, 135);">T</span><span class="" style="font-variant-ligatures: no-common-ligatures;">), anothercase(</span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(79, 129, 135);">U</span><span class="" style="font-variant-ligatures: no-common-ligatures;">) }</span></div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; min-height: 13px;"><span class="" style="font-variant-ligatures: no-common-ligatures;"></span><br class=""></div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;"><span class="" style="font-variant-ligatures: no-common-ligatures;"><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(187, 44, 162);">func</span><span class="" style="font-variant-ligatures: no-common-ligatures;"><span class="Apple-converted-space"> </span>foo<T, U>(instance:<span class="Apple-converted-space"> </span></span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(79, 129, 135);">TypeName</span><span class="" style="font-variant-ligatures: no-common-ligatures;"><</span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(79, 129, 135);">T</span><span class="" style="font-variant-ligatures: no-common-ligatures;">,<span class="Apple-converted-space"> </span></span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(79, 129, 135);">U</span><span class="" style="font-variant-ligatures: no-common-ligatures;">>)</span> {</span></div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;"><span class="" style="font-variant-ligatures: no-common-ligatures;"><span class="Apple-tab-span" style="white-space: pre;">        </span></span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(187, 44, 162);">guard</span><span class="" style="font-variant-ligatures: no-common-ligatures;"><span class="Apple-converted-space"> </span>unwrap instance<span class="Apple-converted-space"> </span></span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(187, 44, 162);">else</span><span class="" style="font-variant-ligatures: no-common-ligatures;"><span class="Apple-converted-space"> </span>{ ... }</span></div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;"><span class="" style="font-variant-ligatures: no-common-ligatures;">}</span></div><div class=""><span class="" style="font-variant-ligatures: no-common-ligatures;"><br class=""></span></div><div class=""><span class="" style="font-variant-ligatures: no-common-ligatures;">What type does instance have? </span></div></div></div></blockquote></div><br class="" style="font-family: Palatino-Roman; font-size: 14px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;"><div class="" style="font-family: Palatino-Roman; font-size: 14px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;">Fair enough. How about: An unwrappable enumeration must have at most one generic type so the compiler can guarantee at compile time that the type is unambiguous if the unwrapping succeeds</div></div></blockquote><br class=""></div><div>And updated gist:</div><div><br class=""></div><div><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); color: rgb(51, 51, 51); font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; background-color: rgb(255, 255, 255);" class="">Detailed Design</h2><p style="box-sizing: border-box; margin-top: 0px; margin-bottom: 16px; color: rgb(51, 51, 51); font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 16px; background-color: rgb(255, 255, 255);" class="">The <code style="box-sizing: border-box; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 13.600000381469727px; padding: 0.2em 0px; margin: 0px; background-color: rgba(0, 0, 0, 0.0392157); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;" class="">unwrap</code> statement shadows an enumeration variable to an unwrapped version of the same type. Using <code style="box-sizing: border-box; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 13.600000381469727px; padding: 0.2em 0px; margin: 0px; background-color: rgba(0, 0, 0, 0.0392157); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;" class="">unwrap</code> is limited to enumerations that satisfy the following conditions:</p><ul style="box-sizing: border-box; padding-left: 2em; margin-top: 0px; margin-bottom: 16px; color: rgb(51, 51, 51); font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 16px; background-color: rgb(255, 255, 255);" class=""><li style="box-sizing: border-box;" class="">An unwrappable enumeration must specify the unwrap type, probably through an <code style="box-sizing: border-box; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 13.600000381469727px; padding: 0.2em 0px; margin: 0px; background-color: rgba(0, 0, 0, 0.0392157); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;" class="">@unwrappable</code> attribute.</li><li style="box-sizing: border-box; margin-top: 0.25em;" class="">Unwrapping is limited to one-item cases with that type.</li><li style="box-sizing: border-box; margin-top: 0.25em;" class="">No-item or multi-item cases cannot unwrap.</li><li style="box-sizing: border-box; margin-top: 0.25em;" class="">Cases using a different associated value type cannot unwrap.</li></ul><pre style="box-sizing: border-box; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 13.600000381469727px; margin-top: 0px; margin-bottom: 16px; line-height: 1.45; word-wrap: normal; padding: 16px; overflow: auto; background-color: rgb(247, 247, 247); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; color: rgb(51, 51, 51);" class=""><code style="box-sizing: border-box; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; padding: 0px; margin: 0px; background-color: transparent; border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; word-break: normal; border: 0px; display: inline; overflow: visible; line-height: inherit; word-wrap: normal;" class="">@unwrappable(type: Wrapped)
public enum Optional<Wrapped> {
case none
case some(Wrapped)
}
@unwrappable(type: ValueType)
public enum Result<ValueType> {
case value(ValueType)
case error(Error)
}
@unwrappable(type: Int)
public enum Count {
case none // not unwrappable
case many // not unwrappable
case some(Int)
case owed(Int)
case something(String) // not unwrappable
case multiple(Int, Int) // not unwrappable
}
</code></pre><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); color: rgb(51, 51, 51); font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; background-color: rgb(255, 255, 255);" class=""><a id="user-content-impact-on-existing-code" class="anchor" href="https://gist.github.com/erica/db9ce92b3d23cb20799460f603c0ae7c#impact-on-existing-code" aria-hidden="true" style="box-sizing: border-box; background-color: transparent; -webkit-text-decoration-skip: objects; color: rgb(64, 120, 192); 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"><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"></path></svg></a></h2></div><br class=""></body></html>