[swift-evolution] [Proposal] Enums with static stored properties foreach case

Patrick Smith pgwsmith at gmail.com
Wed May 25 20:20:25 CDT 2016


Yes, I don’t think it would work with a raw value behaviour. You want it to compile down to the same underlying code as the first example, without having to write lots of switch statements.

Another syntax I could imagine is:

enum Planet {
  var mass: Float { get }
  var radius: Float { get }

  case mercury [
    mass: 3.303e+23,
    radius: 2.4397e6
  ]
  case venus [
    mass: 4.869e+24,
    radius: 6.0518e6
  ]
  case earth [
    mass: 5.976e+24,
    radius: 6.37814e6
  ]
  ...
}


You couldn’t have an initializer, as enums only have storage when they have associated values, which these do not. ‘where’ is used for pattern matching, not declaring as far as I know, so that’s why I suggest this other way.

Patrick

> On 26 May 2016, at 5:50 AM, Jānis Kiršteins via swift-evolution <swift-evolution at swift.org> wrote:
> 
> That would replace current enum raw value functionality and I see two
> problems with that.
> 
> 1. A lot of breaking changes
> 2. Raw values currently are unique values among all cases. That makes
> a possibility that enums can be easily serialized/deserialized to
> formats like JSON, property lists, etc. In "case mercury = (mass:
> 3.303e+23, radius: 2.4397e6)" neither mass nor radius is unique value
> (it is possible that two different planets could have the same mass as
> radius).
> 
> 
> 
> On Wed, May 25, 2016 at 3:37 PM, Leonardo Pessoa <me at lmpessoa.com> wrote:
>> Hi,
>> 
>> Couldn't this be solved by using tuples? If not because the syntax is not
>> allowed I think this would be more coherent to do it using current syntax.
>> 
>> enum Planet : (mass: Float, radius: Float) {
>>    case mercury = (mass: 3.303e+23, radius: 2.4397e6)
>>    case venus = (mass: 4.869e+24, radius: 6.0518e6)
>>    case earth = (mass: 5.976e+24, radius: 6.37814e6)
>>    case mars = (mass: 6.421e+23, radius: 3.3972e6)
>>    case jupiter = (mass: 1.9e+27, radius: 7.1492e7)
>>    case saturn = (mass: 5.688e+26, radius: 6.0268e7)
>>    case uranus = (mass: 8.686e+25, radius: 2.5559e7)
>>    case neptune = (mass: 1.024e+26, radius: 2.4746e7)
>> }
>> ________________________________
>> From: Jānis Kiršteins via swift-evolution
>> Sent: ‎25/‎05/‎2016 08:58 AM
>> To: swift-evolution at swift.org
>> Subject: [swift-evolution] [Proposal] Enums with static stored properties
>> foreach case
>> 
>> Hello everyone,
>> 
>> Currently Swift only supports computed properties for each enum case.
>> If you want to somehow get static values with each case you would
>> probably do it like this:
>> 
>> enum Planet {
>>    case mercury
>>    case venus
>>    case earth
>>    case mars
>>    case jupiter
>>    case saturn
>>    case uranus
>>    case neptune
>> 
>>    var mass: Float {
>>        switch self {
>>        case .mercury: return 3.303e+23
>>        case .venus: return 4.869e+24
>>        case .earth: return 5.976e+24
>>        case .mars: return 6.421e+23
>>        case .jupiter: return 1.9e+27
>>        case .saturn: return 5.688e+26
>>        case .uranus: return 8.686e+25
>>        case .neptune: return 1.024e+26
>>        }
>>    }
>> 
>>    var radius: Float {
>>        switch self {
>>        case .mercury: return 2.4397e6
>>        case .venus: return 6.0518e6
>>        case .earth: return 6.37814e6
>>        case .mars: return 3.3972e6
>>        case .jupiter: return 7.1492e7
>>        case .saturn: return 6.0268e7
>>        case .uranus: return 2.5559e7
>>        case .neptune: return 2.4746e7
>>        }
>>    }
>> }
>> 
>> However I see two problems with this approach:
>> 
>> 1. These value definitions are spread out and difficult to read and
>> maintain (especially if you have many computed properties for each
>> enum case);
>> 2. These values are not static. They are computed each time property
>> is accessed. This can be a problem when value is expensive to create.
>> 
>> The proposed solution is to have single static initializer for each
>> enum case that initializes stored properties. For example,
>> 
>> enum Planet {
>>    var mass: Float
>>    var radius: Float
>> 
>>    static init(mass: Float, radius: Float) {
>>        self.mass = mass
>>        self.radius = radius
>>    }
>> 
>>    case mercury where (mass: 3.303e+23, radius: 2.4397e6)
>>    case venus where (mass: 4.869e+24, radius: 6.0518e6)
>>    case earth where (mass: 5.976e+24, radius: 6.37814e6)
>>    case mars where (mass: 6.421e+23, radius: 3.3972e6)
>>    case jupiter where (mass: 1.9e+27, radius: 7.1492e7)
>>    case saturn where (mass: 5.688e+26, radius: 6.0268e7)
>>    case uranus where (mass: 8.686e+25, radius: 2.5559e7)
>>    case neptune where (mass: 1.024e+26, radius: 2.4746e7)
>> }
>> 
>> This approach do not affect enums that have raw or associated values,
>> or custom enum initializers:
>> 
>> case A = "A" where (id: 0)
>> 
>> or
>> 
>> case B(Int, Int, Int) where (id: 0)
>> 
>> Benefits:
>> 1. Less verbosity
>> 2. Improved readability
>> 3. Related values are closer to each other
>> 4. Static values are not recomputed
>> _______________________________________________
>> 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



More information about the swift-evolution mailing list