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

Vladimir.S svabox at gmail.com
Thu May 26 12:36:20 CDT 2016


On 26.05.2016 19:50, Ross O'Brien wrote:
> Perhaps there's an argument to be made for a sort of 'enumDictionary' type
> - a dictionary whose keys are all the cases of an enum, and is thus
> guaranteed to produce a value.

In Delphi(Pascal) you can define an array with indexes of enum type i.e.:
type
   TMyEnum = (One, Two)
var
   MyVal : array[TMyEnum] of String
const
   MyConsts : array [TMyEnum] of String = ('just one', 'two here')
   // compiler will check that values for each enum were specified here

,so you can do
var e: TMyEnum
e := One;
MyVal[e] := 'hello';
s2 := MyConsts[e];

This is really useful and used a lot. And this is safe in meaning compiler 
will notify you if you changed the enum - you'll have to change such 
constant array.

I wish we'll have something like this in Swift.

>
> I think the question I have is how you'd access the values, syntactically.
> To use the Planet example, if '.earth' is a value of the Planet enum, is
> '.earth.mass' an acceptable way to access its mass? Or perhaps
> 'Planet[.earth].mass'?

Just like .rawValue currently, i.e.
let e = Planet.earth
print(e.mass, e.description)

>
> On Thu, May 26, 2016 at 4:43 PM, Vladimir.S via swift-evolution
> <swift-evolution at swift.org <mailto:swift-evolution at swift.org>> wrote:
>
>     Or(if we are sure we'll don't forget to udpate `infoDict` in case of
>     new added case in future):
>
>     enum Planet {
>         case earth
>         case moon
>
>         struct PlanetInfo {
>             var mass: Double
>             var description: String
>         }
>
>         private static let infoDict = [
>             Planet.earth :
>                 PlanetInfo(mass: 1.0, description:"Earth is our home"),
>             .moon:
>                 PlanetInfo(mass: 0.2, description:"Just a moon"),
>             ]
>
>         var info : PlanetInfo { return Planet.infoDict[self]! }
>     }
>
>     But I agree with you, IMO we need static stored properties for each case.
>
>
>     On 26.05.2016 18 <tel:26.05.2016%2018>:15, Jānis Kiršteins wrote:
>
>         The problem is that PlanetInfo values are recreated each time while
>         they are static. Imagine if PlanetInfo where some type that expensive
>         to create performance wise.
>
>         You could solve it by:
>
>         enum Planet {
>             struct PlanetInfo {
>                 var mass: Double
>                 var description: String
>             }
>
>             case earth
>             case moon
>
>             private static earthInfo = PlanetInfo(mass: 1.0, description:
>         "Earth is our home")
>             private static moonInfo = PlanetInfo(mass: 0.2, description:
>         "Just a moon")
>
>             var info : PlanetInfo {
>                 switch self {
>                     case earth: return PlanetInfo.earthInfo
>                     case moon: return PlanetInfo.moonInfo
>                 }
>             }
>         }
>
>         But that again more verbose. The proposed solution is explicit that
>         those properties are static for each case.
>
>
>         On Thu, May 26, 2016 at 5:58 PM, Vladimir.S via swift-evolution
>         <swift-evolution at swift.org <mailto:swift-evolution at swift.org>> wrote:
>
>             I support the proposal, but couldn't the initial target be
>             achieved today
>             with such (more verbose,yes) solution? :
>
>             enum Planet {
>                 struct PlanetInfo {
>                     var mass: Double
>                     var description: String
>                 }
>
>                 case earth
>                 case moon
>
>                 var info : PlanetInfo {
>                     switch self {
>                         case earth: return PlanetInfo(mass: 1.0,
>             description: "Earth is
>             our home")
>                         case moon: return PlanetInfo(mass: 0.2,
>             description: "Just a
>             moon")
>                     }
>                 }
>             }
>
>
>             let e = Planet.earth
>             print(e, e.info.description)
>
>             let m = Planet.moon
>             print(m, m.info.description)
>
>
>
>             On 26.05.2016 8:26, Charlie Monroe via swift-evolution wrote:
>
>
>                     What this proposal is asking for is an easier way to
>                     have derived values
>                     from enum cases. Asking for more flexible RawValues
>                     means mass and radius
>                     are not derived, they are the source of truth. It goes
>                     against the whole
>                     point of RawRepresentable. You are not saying ‘Mercury
>                     is identified by
>                     the case .mercury’, you are saying ‘Mercury is
>                     identified by a mass of
>                     3.303e+23’. It’s backwards.
>
>
>
>                 I see what Janis meant in the first email. It's not that
>                 the planet would
>                 be identified by the mass or radius. It could very much be
>
>                 case Mercury = 1 where (mass: 3, radius: 2),
>
>                 - Mercury's rawValue would be 1.
>
>                 The issue here is that sometimes you want additional
>                 information with the
>                 enum. There are many cases where you extend the enum with a
>                 variable:
>
>                 enum Error {
>                 case NoError
>                 case FileNotFound
>                 ...
>
>                 var isFatal: Bool {
>                 /// swtich over all values of self goes here.
>                 }
>
>                 var isNetworkError: Bool {
>                 /// swtich over all values of self goes here.
>                 }
>
>                 var isIOError: Bool {
>                 /// swtich over all values of self goes here.
>                 }
>                 }
>
>                 What the propsal suggests is to simplify this to the following:
>
>                 enum Error {
>                 var isFatal: Bool
>
>                 case NoError where (isFatal: false, isNetworkError: false,
>                 isIOError:
>                 false)
>                 case FileNotFound  where (isFatal: true, isNetworkError:
>                 false, isIOError:
>                 true)
>                 ...
>
>                 }
>
>                 So that you assign the additional information to the enum
>                 value itself.
>
>                 Charlie
>
>
>
>                         On 26 May 2016, at 1:47 PM, David Sweeris via
>                         swift-evolution
>                         <swift-evolution at swift.org
>                         <mailto:swift-evolution at swift.org>
>                         <mailto:swift-evolution at swift.org
>                         <mailto:swift-evolution at swift.org>>> wrote:
>
>
>                             On May 25, 2016, at 10:27 PM, Jacob
>                             Bandes-Storch <jtbandes at gmail.com
>                             <mailto:jtbandes at gmail.com>
>                             <mailto:jtbandes at gmail.com
>                             <mailto:jtbandes at gmail.com>>> wrote:
>
>                             On Wed, May 25, 2016 at 8:15 PM, David Sweeris
>                             via swift-evolution
>                             <swift-evolution at swift.org
>                             <mailto:swift-evolution at swift.org>
>                             <mailto:swift-evolution at swift.org
>                             <mailto:swift-evolution at swift.org>>> wrote:
>
>                                 On May 25, 2016, at 7:37 AM, Leonardo
>                             Pessoa via swift-evolution
>                                 <swift-evolution at swift.org
>                             <mailto:swift-evolution at swift.org>
>                             <mailto:swift-evolution at swift.org
>                             <mailto:swift-evolution at swift.org>>>
>                             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)
>                                     }
>
>
>
>                                 This would be my preferred solution… AFAIK,
>                             the only reason we
>                                 can’t do it now is that Swift currently
>                             requires RawValue be an
>                                 integer, floating-point value, or string. I
>                             don’t know why the
>                                 language has this restriction, so I can’t
>                             comment on how hard it
>                                 would be to change.
>
>                                 - Dave Sweeris
>
>
>                             Except you'd have to write
>                             Planet.mercury.rawValue.mass, rather than
>                             Planet.mercury.mass.
>
>                             This could be one or two proposals: allow enums
>                             with tuple RawValues,
>                             and allow `TupleName.caseName.propertyName` to
>                             access a tuple element
>                             without going through .rawValue.
>
>
>
>                         Good point… Has there been a thread on allowing
>                         raw-valued enums to be
>                         treated as constants of type `RawValue` yet? Either
>                         way, removing the
>                         restriction on what types can be a RawValue is
>                         still my preferred
>                         solution.
>
>                         - Dave Sweeris
>                         _______________________________________________
>                         swift-evolution mailing list
>                         swift-evolution at swift.org
>                         <mailto:swift-evolution at swift.org>
>                         <mailto:swift-evolution at swift.org
>                         <mailto:swift-evolution at swift.org>>
>                         https://lists.swift.org/mailman/listinfo/swift-evolution
>
>
>
>                     _______________________________________________
>                     swift-evolution mailing list
>                     swift-evolution at swift.org
>                     <mailto:swift-evolution at swift.org>
>                     <mailto:swift-evolution at swift.org
>                     <mailto:swift-evolution at swift.org>>
>                     https://lists.swift.org/mailman/listinfo/swift-evolution
>
>
>
>
>
>                 _______________________________________________
>                 swift-evolution mailing list
>                 swift-evolution at swift.org <mailto:swift-evolution at swift.org>
>                 https://lists.swift.org/mailman/listinfo/swift-evolution
>
>             _______________________________________________
>             swift-evolution mailing list
>             swift-evolution at swift.org <mailto:swift-evolution at swift.org>
>             https://lists.swift.org/mailman/listinfo/swift-evolution
>
>
>     _______________________________________________
>     swift-evolution mailing list
>     swift-evolution at swift.org <mailto:swift-evolution at swift.org>
>     https://lists.swift.org/mailman/listinfo/swift-evolution
>
>


More information about the swift-evolution mailing list