[swift-evolution] [Proposal] Enums with stored properties

Mateusz Malczak mateusz at malczak.info
Sat Oct 8 13:42:49 CDT 2016


Hi all,
I would like to know you opinion on one feature I feel would be a real
'nice to have' extension to currently available enumeration type. Which is
an enumeration type with stored properties. It is sometimes useful to store
some extra informations along with enumeration cases. Idea here is to add
possibility to define an enumeration type with stored, immutable,
properties, defined at compile time for all cases. In opposition to
currently available associated values, stored properties should be constant
values stored as a part of enumeration case. Proposed feature would be
treated as a new feature along the associated values and raw values.

Please take a look at an example to illustrate this:
```swift
enum Format {
    case SMALL(30, 30)
    case MEDIUM(60, 60)
    case LARGE(120, 120)
    var width: Double
    var height: Double
    init(width: Double, height: Double) {
        self.width = width
        self.height = height
    }
}
```

Similar feature is currently available for example in Java (
http://docs.oracle.com/javase/tutorial/java/javaOO/enum.html).

Currently there are at least tree ways to solve this limitation.

1. use enumeration type with custom struct as a rawValue cons:
a lot of additional code to define structs and implement
`ExpressibleByStringLiteral`
not really possible for more complex types, where a complex string parser
would be required

example:
```swift
struct FormatStruct: ExpressibleByStringLiteral, Equatable {
    var width: Int = 0
    var height: Int = 0
    public init(width: Int, height: Int) {
        self.width = width
        self.height = height
    }
    public init(stringLiteral value: String) {
        let set = CharacterSet(charactersIn: "x")
        let values = value.components(separatedBy: set)
        if let width = Int(values[0]), let height = Int(values[1]) {
            self.init(width: width, height: height)
        } else {
            self.init(width: 0, height: 0)
        }
    }
    init(extendedGraphemeClusterLiteral value: String){
        self.init(stringLiteral: value)
    }
    init(unicodeScalarLiteral value: String) {
        self.init(stringLiteral: value)
    }
    static func ==(lhs: FormatStruct, rhs: FormatStruct) -> Bool {
        return (lhs.width == rhs.width) && (lhs.height == rhs.height)
    }
    static let A = FormatStruct(width: 30, height: 30)
}
enum Format: FormatStruct {
    case SMALL = "30x30"
    case MEDIUM = "60x60"
    case LARGE = "120x120"
    var width: Int {
        return rawValue.width
    }
    var height: Int {
        return rawValue.height
    }
}
```

2. static struct values to mimic enumeration type
cons:
enum should be used to define a closed set of possible values

example:
```swift
struct Format: ExpressibleByStringLiteral, Equatable {
    var width: Int = 0
    var height: Int = 0
    public init(width: Int, height: Int) {
        self.width = width
        self.height = height
    }
    static let SMALL = FormatStruct(width: 30, height: 30)
    static let MEDIUM = FormatStruct(width: 60, height: 60)
    static let LARGE = FormatStruct(width: 120, height: 120)
}
```

3. define enum with getters
cons:
additional, repeated `switch` clauses in getters

example:
```swift
enum Format2 { case SMALL case MEDIUM case LARGE var width: Int { switch
self { case .SMALL: return 30 case .MEDIUM: return 60 case .LARGE: return
120 } } var height: Int { switch self { case .SMALL: return 30 case
.MEDIUM: return 60 case .LARGE: return 120 } } }
```

What is your opinion on this feature? Or maybe that was not implemented for
some reason - if so can I get an few word of explaination what was the
motivation for not adding this to the language?

best regards
--
| Mateusz Malczak
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20161008/d3ed5232/attachment.html>


More information about the swift-evolution mailing list