<html><head><meta http-equiv="content-type" content="text/html; charset=utf-8"></head><body dir="auto"><div><span></span></div><div><div><br></div><div>On Jun 1, 2016, at 1:06 PM, Haravikk via swift-evolution <<a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a>> wrote:<br><br></div><blockquote type="cite"><div><meta http-equiv="Content-Type" content="text/html charset=utf-8"><div class="">I agree the second is much nicer, and a lot clearer on what each of the options does; fitImage: true is pretty clear, but fitImage: false is not, but the ad-hoc enum is clear on both counts. That said, the questions of interoperability are a big issue for ad-hoc enums, as either they’re too strict which becomes inconvenient (a .Fit | .Fill working with one method but not another) or too relaxed to be safe. Of course, in the latter case you’re replacing a Bool, which couldn’t be more relaxed in terms of where it accepts values from.</div><div class=""><br class=""></div><div class="">Still, I think in this case it would be better to fully-define an enum, as it gives you total control over compatibility and reusability of the type, which you can’t really with the ad-hoc form without making it overly complex.</div><div class=""><br class=""></div><div class="">The main type of ad-hoc enum I want to see is a union-type like so:</div><div class=""><br class=""></div><div class=""><font face="Monaco" class=""><span class="Apple-tab-span" style="white-space:pre">        </span>func someMethod(value:(Int | String)) { … }</font></div><div class=""><br class=""></div><div class="">This would basically be an ad-hoc enum where each case identifies one of the possible types, and the value bound as that type. This works however because there’s no ambiguity in the meaning; an (Int | String) is the same wherever you use it, whereas a general-purpose ad-hoc enum is less clear, as an other method might also take .Fit and .Fill values, but these may have a slightly different meaning.</div><div class=""><br class=""></div><div class="">So yeah, I like the idea in principle, but I think in practice it has too many headaches to overcome for it to be as simple as it first appears =(</div><br class=""><div><blockquote type="cite" class=""><div class="">On 31 May 2016, at 17:16, Erica Sadun 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=""><meta http-equiv="Content-Type" content="text/html charset=us-ascii" class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class="">Here's a function signature from some code from today:<div class=""><br class=""></div><div class=""><table class="highlight js-file-line-container tab-size" data-tab-size="8" style="box-sizing: border-box; border-spacing: 0px; border-collapse: collapse; tab-size: 8; color: rgb(51, 51, 51); font-family: Helvetica, arial, nimbussansl, liberationsans, freesans, clean, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 13px;"><tbody style="box-sizing: border-box;" class=""><tr style="box-sizing: border-box;" class=""><td id="file-scalecrop-swift-LC6" class="js-file-line blob-code-inner blob-code" style="box-sizing: border-box; padding: 0px 10px; position: relative; vertical-align: top; overflow: visible; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 12px; word-wrap: normal; white-space: pre;"><span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">func</span> <span class="pl-en" style="box-sizing: border-box; color: rgb(121, 93, 163);">scaleAndCropImage</span>(</td></tr><tr style="box-sizing: border-box;" class=""><td id="file-scalecrop-swift-L7" class="blob-num js-line-number" data-line-number="7" style="box-sizing: border-box; padding: 0px 10px; width: 50px; min-width: 50px; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 12px; line-height: 18px; text-align: right; white-space: nowrap; vertical-align: top; cursor: pointer; -webkit-user-select: none; border-style: solid; border-color: rgb(238, 238, 238); border-width: 0px 1px 0px 0px;"></td><td id="file-scalecrop-swift-LC7" class="js-file-line blob-code-inner blob-code" style="box-sizing: border-box; padding: 0px 10px; position: relative; vertical-align: top; overflow: visible; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 12px; word-wrap: normal; white-space: pre;"> image: UIImage,</td></tr><tr style="box-sizing: border-box;" class=""><td id="file-scalecrop-swift-L8" class="blob-num js-line-number" data-line-number="8" style="box-sizing: border-box; padding: 0px 10px; width: 50px; min-width: 50px; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 12px; line-height: 18px; text-align: right; white-space: nowrap; vertical-align: top; cursor: pointer; -webkit-user-select: none; border-style: solid; border-color: rgb(238, 238, 238); border-width: 0px 1px 0px 0px;"></td><td id="file-scalecrop-swift-LC8" class="js-file-line blob-code-inner blob-code" style="box-sizing: border-box; padding: 0px 10px; position: relative; vertical-align: top; overflow: visible; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 12px; word-wrap: normal; white-space: pre;"> <span class="pl-en" style="box-sizing: border-box; color: rgb(121, 93, 163);">toSize</span> <span class="pl-smi" style="box-sizing: border-box;">size</span>: CGSize,</td></tr><tr style="box-sizing: border-box;" class=""><td id="file-scalecrop-swift-L9" class="blob-num js-line-number" data-line-number="9" style="box-sizing: border-box; padding: 0px 10px; width: 50px; min-width: 50px; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 12px; line-height: 18px; text-align: right; white-space: nowrap; vertical-align: top; cursor: pointer; -webkit-user-select: none; border-style: solid; border-color: rgb(238, 238, 238); border-width: 0px 1px 0px 0px;"></td><td id="file-scalecrop-swift-LC9" class="js-file-line blob-code-inner blob-code" style="box-sizing: border-box; padding: 0px 10px; position: relative; vertical-align: top; overflow: visible; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 12px; word-wrap: normal; white-space: pre;"> <b class="">fitImage: <span class="pl-c1" style="box-sizing: border-box; color: rgb(0, 134, 179);">Bool</span> <span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">=</span> <span class="pl-c1" style="box-sizing: border-box; color: rgb(0, 134, 179);">true</span></b></td></tr><tr style="box-sizing: border-box;" class=""><td id="file-scalecrop-swift-L10" class="blob-num js-line-number" data-line-number="10" style="box-sizing: border-box; padding: 0px 10px; width: 50px; min-width: 50px; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 12px; line-height: 18px; text-align: right; white-space: nowrap; vertical-align: top; cursor: pointer; -webkit-user-select: none; border-style: solid; border-color: rgb(238, 238, 238); border-width: 0px 1px 0px 0px;"></td><td id="file-scalecrop-swift-LC10" class="js-file-line blob-code-inner blob-code" style="box-sizing: border-box; padding: 0px 10px; position: relative; vertical-align: top; overflow: visible; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 12px; word-wrap: normal; white-space: pre;"> ) <span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">-></span> UIImage {</td></tr></tbody></table><div class=""><br class=""></div><div class=""><br class=""></div><div class="">And here's what I want the function signature to actually look like:</div></div><div class=""><br class=""></div><div class=""><table class="highlight js-file-line-container tab-size" data-tab-size="8" style="box-sizing: border-box; border-spacing: 0px; border-collapse: collapse; tab-size: 8; color: rgb(51, 51, 51); font-family: Helvetica, arial, nimbussansl, liberationsans, freesans, clean, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 13px;"><tbody style="box-sizing: border-box;" class=""><tr style="box-sizing: border-box;" class=""><td id="file-scalecrop-swift-LC6" class="js-file-line blob-code-inner blob-code" style="box-sizing: border-box; padding: 0px 10px; position: relative; vertical-align: top; overflow: visible; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 12px; word-wrap: normal; white-space: pre;"><span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">func</span> <span class="pl-en" style="box-sizing: border-box; color: rgb(121, 93, 163);">scaleAndCropImage</span>(</td></tr><tr style="box-sizing: border-box;" class=""><td id="file-scalecrop-swift-L7" class="blob-num js-line-number" data-line-number="7" style="box-sizing: border-box; padding: 0px 10px; width: 50px; min-width: 50px; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 12px; line-height: 18px; text-align: right; white-space: nowrap; vertical-align: top; cursor: pointer; -webkit-user-select: none; border-style: solid; border-color: rgb(238, 238, 238); border-width: 0px 1px 0px 0px;"></td><td id="file-scalecrop-swift-LC7" class="js-file-line blob-code-inner blob-code" style="box-sizing: border-box; padding: 0px 10px; position: relative; vertical-align: top; overflow: visible; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 12px; word-wrap: normal; white-space: pre;"> image: UIImage,</td></tr><tr style="box-sizing: border-box;" class=""><td id="file-scalecrop-swift-L8" class="blob-num js-line-number" data-line-number="8" style="box-sizing: border-box; padding: 0px 10px; width: 50px; min-width: 50px; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 12px; line-height: 18px; text-align: right; white-space: nowrap; vertical-align: top; cursor: pointer; -webkit-user-select: none; border-style: solid; border-color: rgb(238, 238, 238); border-width: 0px 1px 0px 0px;"></td><td id="file-scalecrop-swift-LC8" class="js-file-line blob-code-inner blob-code" style="box-sizing: border-box; padding: 0px 10px; position: relative; vertical-align: top; overflow: visible; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 12px; word-wrap: normal; white-space: pre;"> <span class="pl-en" style="box-sizing: border-box; color: rgb(121, 93, 163);">toSize</span> <span class="pl-smi" style="box-sizing: border-box;">size</span>: CGSize,</td></tr><tr style="box-sizing: border-box;" class=""><td id="file-scalecrop-swift-L9" class="blob-num js-line-number" data-line-number="9" style="box-sizing: border-box; padding: 0px 10px; width: 50px; min-width: 50px; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 12px; line-height: 18px; text-align: right; white-space: nowrap; vertical-align: top; cursor: pointer; -webkit-user-select: none; border-style: solid; border-color: rgb(238, 238, 238); border-width: 0px 1px 0px 0px;"></td><td id="file-scalecrop-swift-LC9" class="js-file-line blob-code-inner blob-code" style="box-sizing: border-box; padding: 0px 10px; position: relative; vertical-align: top; overflow: visible; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 12px; word-wrap: normal; white-space: pre;"> <b class="">operation: <font color="#0086b3" class="">(.Fit | .Fill)</font> <span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">=</span> .<font color="#0086b3" class="">Fit</font></b></td></tr><tr style="box-sizing: border-box;" class=""><td id="file-scalecrop-swift-L10" class="blob-num js-line-number" data-line-number="10" style="box-sizing: border-box; padding: 0px 10px; width: 50px; min-width: 50px; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 12px; line-height: 18px; text-align: right; white-space: nowrap; vertical-align: top; cursor: pointer; -webkit-user-select: none; border-style: solid; border-color: rgb(238, 238, 238); border-width: 0px 1px 0px 0px;"></td><td id="file-scalecrop-swift-LC10" class="js-file-line blob-code-inner blob-code" style="box-sizing: border-box; padding: 0px 10px; position: relative; vertical-align: top; overflow: visible; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 12px; word-wrap: normal; white-space: pre;"> ) <span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">-></span> UIImage {</td></tr></tbody></table><div class=""><br class=""></div></div></div></div></blockquote></div></div></blockquote><div><br></div><div>I think it is a very reasonable proposal that does not violate the language.</div><div><br></div><div>Enums are nominal types, so what makes them unique is their names. It means that the name CANNOT be RANDOMLY generated... But it does not mean that the name cannot be meaningfully generated... So it is perfectly reasonable for the compiler to behave like a beginer programmer might and go through a naive but predictable heuristic to derive a semantically meaningful unique name:</div><div><br></div><div>Public enum enum_Fit_OR_Fill {</div><div> case Fit</div><div> case Fill</div><div>}</div><div><br></div><div>The prefix may not even be required. There is no chance that the name would wind up colliding with something done manually, and fixing the declaration to be systematically done at the module level would ensure clear visibility. The method signature would also be clean with "operation" exposed as:</div><div> operation: enum_Fit_OR_Fill</div><div><br></div><div>To deal with milti site definition, the compiler would simply flag a error/warning, or be silent in the presence of a new annotation:</div><div><br></div><div>@strawman_use_synthesised_enum func scaleAndCropImage(....)</div><div><br></div><div>This would indicate that we acknowledge taking full responsibility for avoiding name collisions</div><div><br></div><div>To be more defensive, there could be a rule stating that these cannot be exported from modules (basically cannot be API). This is nothing more than a simple exercise of syntax sugaring...</div><div><br></div><div>Now having said that, if I recall, chris was clear that sugaring in NOT for 3.0</div><div><br></div><br><blockquote type="cite"><div><div><blockquote type="cite" class=""><div class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class=""><br class=""></div><div class="">where I don't have to establish a separate enumeration to include ad-hoc enumeration-like semantics for the call. A while back, Yong hee Lee introduced anonymous enumerations (and the possibility of anonymous option flags) but the discussion rather died.</div><div class=""><br class=""></div><div class="">I'm bringing it up again to see whether there is any general interest in pursuing this further as I think the second example is more readable, appropriate, and Swifty than the first, provides better semantics, and is more self documenting.</div><div class=""><br class=""></div><div class="">Thanks for your feedback,</div><div class=""><br class=""></div><div class="">-- Erica</div><div class=""><br class=""></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></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></div></body></html>