<html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class="">Not a response to the core of this, but to the motivating example: Sectioned (or multi-sorted in other cases) ASTs can also be represented by a singly-sorted AST and views over top<div class=""><br class=""></div><div class=""><div style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);" class=""><span style="color: #ba2da2" class="">enum</span> UnaryOperatorView {</div><div style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);" class="">&nbsp; <span style="color: #ba2da2" class="">case</span> not</div><div style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);" class="">}</div><div style="margin: 0px; font-stretch: normal; line-height: normal; background-color: rgb(255, 255, 255); min-height: 14px;" class=""><br class=""></div><div style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);" class=""><span style="color: #ba2da2" class="">enum</span> BinaryOperatorView {</div><div style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);" class="">&nbsp; <span style="color: #ba2da2" class="">case</span> and</div><div style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);" class="">&nbsp; <span style="color: #ba2da2" class="">case</span> or</div><div style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);" class="">}</div><div style="margin: 0px; font-stretch: normal; line-height: normal; background-color: rgb(255, 255, 255); min-height: 14px;" class=""><br class=""></div><div style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);" class=""><span style="color: #ba2da2" class="">enum</span> BooleanLiteralView {</div><div style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);" class="">&nbsp; <span style="color: #ba2da2" class="">case</span> `true`</div><div style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);" class="">&nbsp; <span style="color: #ba2da2" class="">case</span> `false`</div><div style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);" class="">}</div><div style="margin: 0px; font-stretch: normal; line-height: normal; background-color: rgb(255, 255, 255); min-height: 14px;" class=""><br class=""></div><div style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);" class=""><span style="color: #ba2da2" class="">enum</span> Token {</div><div style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);" class="">&nbsp; <span style="color: #ba2da2" class="">case</span> not</div><div style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);" class="">&nbsp; <span style="color: #ba2da2" class="">case</span> and, or</div><div style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);" class="">&nbsp; <span style="color: #ba2da2" class="">case</span> `true`, `false`</div><p style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255); min-height: 13px;" class="">&nbsp;&nbsp;<br class="webkit-block-placeholder"></p><div style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);" class="">&nbsp; <span style="color: #ba2da2" class="">var</span> asUnaryOperator: <span style="color: #4f8187" class="">UnaryOperatorView</span>? {</div><div style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(186, 45, 162); background-color: rgb(255, 255, 255);" class=""><span style="color: #000000" class="">&nbsp; &nbsp; </span>switch<span style="color: #000000" class=""> </span>self<span style="color: #000000" class=""> {</span></div><div style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(186, 45, 162); background-color: rgb(255, 255, 255);" class=""><span style="color: #000000" class="">&nbsp; &nbsp; </span>case<span style="color: #000000" class=""> .</span><span style="color: #31595d" class="">not</span><span style="color: #000000" class="">: </span>return<span style="color: #000000" class=""> .</span><span style="color: #31595d" class="">not</span></div><div style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(186, 45, 162); background-color: rgb(255, 255, 255);" class=""><span style="color: #000000" class="">&nbsp; &nbsp; </span>default<span style="color: #000000" class="">: </span>return<span style="color: #000000" class=""> </span>nil</div><div style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);" class="">&nbsp; &nbsp; }</div><div style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);" class="">&nbsp; }</div><p style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255); min-height: 13px;" class="">&nbsp;&nbsp;<br class="webkit-block-placeholder"></p><div style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(0, 132, 0); background-color: rgb(255, 255, 255);" class=""><span style="color: #000000" class="">&nbsp; </span>/*etc.*/</div><div style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);" class="">}</div><div class=""><br class=""></div><div class="">The&nbsp;<a href="https://github.com/typelift/Valence/blob/master/Tests/SystemF.swift#L111" class="">Valence library uses this to great effect</a>.</div><div><br class=""></div><div>~Robert Widmann</div><div><br class=""><blockquote type="cite" class=""><div class="">On Jul 31, 2017, at 5:43 PM, Ahmad Alhashemi 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=""><div class="">I’ve been writing an interpreter in Swift and have been finding enums incredibly useful. One feature thought that I thought would make life easier is the ability to create a super-enum that contains as its cases all the cases of its constituent enums:<br class=""><br class=""><blockquote type="cite" class="">enum UnaryOperator {<br class=""> &nbsp;&nbsp;&nbsp;case not<br class="">}<br class=""><br class="">enum BinaryOperator {<br class=""> &nbsp;&nbsp;&nbsp;case and<br class=""> &nbsp;&nbsp;&nbsp;case or<br class="">}<br class=""><br class="">case BooleanLiteral {<br class=""> &nbsp;&nbsp;&nbsp;case `true`<br class=""> &nbsp;&nbsp;&nbsp;case `false`<br class="">}<br class=""><br class="">typealias Token = UnaryOperator | BinaryOperator | BooleanLiteral<br class=""></blockquote><br class="">It would then be possible to do something like this:<br class=""><br class=""><blockquote type="cite" class="">scanToken() -&gt; Token<br class=""><br class="">indirect enum Expr {<br class=""> &nbsp;&nbsp;&nbsp;case binary(op: BinaryOperator, lhs: Expr, rhs: Expr)<br class="">}<br class=""></blockquote><br class="">For example, a number of functions in the recursive descent parser can only return a subset of all possible expressions.<br class=""><br class="">Of course it’s already possible to represent the same data structure like this:<br class=""><br class=""><blockquote type="cite" class="">enum Token {<br class=""> &nbsp;&nbsp;&nbsp;case binaryOperator(BinaryOperator)<br class=""> &nbsp;&nbsp;&nbsp;case unaryOperator(UnaryOperator)<br class=""> &nbsp;&nbsp;&nbsp;case booleanLiteral(BooleanLiteral)<br class="">}<br class=""></blockquote><br class="">Perhaps what I’m suggesting could just be syntactic sugar, but it’d make it much easier to switch over `Token` without worrying about all of the nested enums. The feature becomes even more useful if you think about a deeper hierarchy of enums. It would bring some of the power of protocols/POP to enums.<br class=""><br class="">This raises a few questions such as:<br class="">- Case name collisions<br class="">- Associated types<br class="">- Raw values<br class=""><br class="">But I can’t think of anything that cannot be addressed with sensible rules and conditions.<br class=""><br class="">Interested to read your thoughts.<br class=""><br class="">-Ahmad<br class="">_______________________________________________<br class="">swift-evolution mailing list<br class=""><a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a><br class="">https://lists.swift.org/mailman/listinfo/swift-evolution<br class=""></div></div></blockquote></div><br class=""></div></body></html>