[swift-evolution] [Proposal] Enums with static stored propertiesforeach case

Patrick Smith pgwsmith at gmail.com
Wed May 25 21:15:43 CDT 2016


Yes, that would be a great behaviour, but that’s exactly how enums with raw values do not work. The enum cases transform to and from an external representable form, that’s why it is ‘RawRepresentable’. So in your example of tuples, that representable form would be the tuple values themselves.

I agree about having enum cases as strings is handy. For your described case it is best to use a String as the raw value type, and the derived values as calculated properties. It would be handy, as we are discussing, to declare those calculated properties in an easier manner, and I would’t mind if it used a tuple syntax. But it should’t be used as the underlying value, as this is the source of ‘truth’ for the enum.


> On 26 May 2016, at 12:09 PM, Leonardo Pessoa <me at lmpessoa.com> wrote:
> 
> I'd still go with tuple syntax as it feels more like a natural extension to current enum syntax and does not introduce new elements to the syntax of enums (other than add tuples as a possible enum value type) thus being simpler and faster to implement and learn than a new syntax built specifically for this kind of construction.
> 
> As I mentioned before, the issue with JSON and other engines trying to record the raw value instead of the enum seems to me as a wrong implementation choice of the engine. Previous to Swift enums I've always seen enum cases the same as constants and any additional values they'd hold are associated with that constant and not persisted. This may also be a thing from the company I work for today that choses to store the names of the enum cases (as strings) in databases and any values associated with them are recovered from the enum case constant. Of course the language I work with supports finding the enum value by its name, which it seems Swift doesn't.
> 
> From: Patrick Smith <mailto:pgwsmith at gmail.com>
> Sent: ‎25/‎05/‎2016 10:20 PM
> To: Jānis Kiršteins <mailto:janis.kirsteins at gmail.com>
> Cc: Leonardo Pessoa <mailto:me at lmpessoa.com>; swift-evolution at swift.org <mailto:swift-evolution at swift.org>
> Subject: Re: [swift-evolution] [Proposal] Enums with static stored propertiesforeach case
> 
> 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
> 

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160526/fa9f72d8/attachment.html>


More information about the swift-evolution mailing list