[swift-evolution] [Idea] Creating an enums as a sum of multiple other enums

Robert Bennett rltbennett at icloud.com
Mon Jul 31 21:54:09 CDT 2017


That solution seems way too verbose, and also not exactly type safe because you must handle optionals in addition to any new cases that arise, which are silently handled by the default case.

To Xiaodi: is this really just value subtyping? Seems like it would also require multiple inheritance for it to work as suggested. To me this seems more like sugar for an Either type containing an arbitrary number of types (actually a special case of that because it’s restricted to enums).

Either way it gets a big +1 from me.

> On Jul 31, 2017, at 10:04 PM, Robert Widmann via swift-evolution <swift-evolution at swift.org> wrote:
> 
> 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
> 
> enum UnaryOperatorView {
>   case not
> }
> 
> enum BinaryOperatorView {
>   case and
>   case or
> }
> 
> enum BooleanLiteralView {
>   case `true`
>   case `false`
> }
> 
> enum Token {
>   case not
>   case and, or
>   case `true`, `false`
>   
>   var asUnaryOperator: UnaryOperatorView? {
>     switch self {
>     case .not: return .not
>     default: return nil
>     }
>   }
>   
>   /*etc.*/
> }
> 
> The Valence library uses this to great effect.
> 
> ~Robert Widmann
> 
>> On Jul 31, 2017, at 5:43 PM, Ahmad Alhashemi via swift-evolution <swift-evolution at swift.org> wrote:
>> 
>> 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:
>> 
>>> enum UnaryOperator {
>>>    case not
>>> }
>>> 
>>> enum BinaryOperator {
>>>    case and
>>>    case or
>>> }
>>> 
>>> case BooleanLiteral {
>>>    case `true`
>>>    case `false`
>>> }
>>> 
>>> typealias Token = UnaryOperator | BinaryOperator | BooleanLiteral
>> 
>> It would then be possible to do something like this:
>> 
>>> scanToken() -> Token
>>> 
>>> indirect enum Expr {
>>>    case binary(op: BinaryOperator, lhs: Expr, rhs: Expr)
>>> }
>> 
>> For example, a number of functions in the recursive descent parser can only return a subset of all possible expressions.
>> 
>> Of course it’s already possible to represent the same data structure like this:
>> 
>>> enum Token {
>>>    case binaryOperator(BinaryOperator)
>>>    case unaryOperator(UnaryOperator)
>>>    case booleanLiteral(BooleanLiteral)
>>> }
>> 
>> 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.
>> 
>> This raises a few questions such as:
>> - Case name collisions
>> - Associated types
>> - Raw values
>> 
>> But I can’t think of anything that cannot be addressed with sensible rules and conditions.
>> 
>> Interested to read your thoughts.
>> 
>> -Ahmad
>> _______________________________________________
>> swift-evolution mailing list
>> swift-evolution at swift.org
>> https://lists.swift.org/mailman/listinfo/swift-evolution
> 
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20170731/9d02b6bd/attachment.html>


More information about the swift-evolution mailing list