[swift-evolution] [Proposal] Enums with static storedpropertiesforeach case

Vladimir.S svabox at gmail.com
Thu May 26 16:15:20 CDT 2016


IMO (now I agree with Leonardo) all we need is allowing a tuple as raw type 
for enum and in this case compiler should allow as to skip '.rawValue.' and 
to use tuple values on enum instance directly like:

enum Planets: (mass: Double, description: String) {
   case earth = (mass: 1.0, description: "Earth")
   case moon = (mass: 0.2, description: "Moon")
}

print(Planets.earth.mass)

But for this, enum should allows raw type representation not just by 
Int/Double/String as now(correct me if forgot something), but at least by 
tuple.
Currently we can actually have enum Planet : PlanetInfo, but raw value 
could be represented only with string like

enum Planet : PlanetInfo {
     case earth = "earth" // represents PlanetInfo(1.0, "Earth")
     case moon = "moon" // represents PlanetInfo(0.2, "Moon")
}
and then use:
print(Planets.earth.rawValue.mass)

But you need a lot(relative) of code to make simple PlanetInfo struct 
RawRepresentable+StringLiteralConvertible+Equatable

Do we actually have some proposal for enum improvement? I mean at least 
'.allValues' feature and this 'tuple raw value' feature?
Probably additionally I'd like to see some '.next/.prev' methods for enums 
without associated values.

On 26.05.2016 23:27, Charlie Monroe wrote:
> I personally don't like the Java values() solution. Nor the solution based
> on dictionary where you need to use ! to unwrap the optionals.
>
> There are IMHO only two ways to solve this:
>
> 1) allow enums with RawValue being object (AnyClass) and make allow case
> values to be computed. In the Planet case:
>
> enum Planets: Planet {
> case Earth = Planet(mass: 1, radius: 2)
> ...
> }
>
> The switch would be performed using ===, i.e. it would be allowed to have
> two cases with the same mass and radius.
>
> This unfortunately faces a lot of issues, including if you have an ObjC
> class that may returns in all cases a singleton and all cases would have
> the same value. This could be handled by an assertion at launch.
>
>
> 2) allow auto-generation of computed variables on enums (partially as I've
> proposed):
>
> enum Planets {
> @auto var mass: Double /// @auto indicates it's auto-generated
> @auto var radius: Double
>
> /// The enum value is .Earth and has mass and radius properties.
> /// All cases would need to declare these and only literals would
> /// be allowed - i.e. numbers + strings.
> case Earth where (mass: 1.0, radius: 2.0)
> ...
>
> }
>
> which would do nothing else than create the following code:
>
> enum Planets {
> var mass: Double {
> switch self {
> case .Earth: return 1.0
> ...
> }
> }
>
> var radius: Double {
> switch self {
> case .Earth: return 2.0
> ...
> }
> }
>
> case Earth
> }
>
>
>
>> On May 26, 2016, at 10:03 PM, Leonardo Pessoa via swift-evolution
>> <swift-evolution at swift.org <mailto:swift-evolution at swift.org>> wrote:
>>
>> I get it and think this was really very interesting in Delphi and I
>> wouldn't mind having something like this in Swift. But despite being able
>> to extend associated information through the use of another array we'd
>> still have more verbosity and scattering than with tuples to implement
>> the examples discussed. And we can already have enum dictionaries just
>> not checking automatically if all enum values have been covered. Moreover
>> there is no loss in having both solutions.
>>
>> I mentioned the values() method also because I miss a way to iterate
>> through all the values on an enum and since it seems we're discussing the
>> entire way to work with enums here it was worth bringing it up.
>>
>> ---------------------------------------------------------------------------
>> From: Vladimir.S <mailto:svabox at gmail.com>
>> Sent: ‎26/‎05/‎2016 03:06 PM
>> To: Leonardo Pessoa <mailto:me at lmpessoa.com>
>> Cc: swift-evolution <mailto:swift-evolution at swift.org>
>> Subject: Re: [swift-evolution] [Proposal] Enums with static
>> storedpropertiesforeach case
>>
>> Yes, this was mentioned in a similar thread in this email list earlier.
>> There is even some proposal for such .values() for Swift enums.
>>
>> But this values() in Java is not the same thing as discussed dictionary
>> with *keys* of enum type or Delphi's arrays with *index* of enum type.
>>
>> Could you write Java's example for array/dictionary of String which
>> *index*(or key) will be of enum type? *And* compiler will check that value
>> for each enum case is set in case of array of constants like:
>> MyConsts : array [TMyEnum] of String = ('just one', 'two here')
>> // compiler will always check that value assigned for each case
>>
>>
>> On 26.05.2016 20:58, Leonardo Pessoa wrote:
>> > Java enums automatically have a static values() method that return an array
>> > with all values in an enum.
>> > ---------------------------------------------------------------------------
>> > From: Vladimir.S via swift-evolution <mailto:swift-evolution at swift.org>
>> > Sent: ‎26/‎05/‎2016 02:36 PM
>> > To: Ross O'Brien <mailto:narrativium+swift at gmail.com>
>> > Cc: swift-evolution <mailto:swift-evolution at swift.org>
>> > Subject: Re: [swift-evolution] [Proposal] Enums with static stored
>> > propertiesforeach case
>> >
>> > 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>
>> <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>
>> <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
>> >>                         <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
>> >>                             <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
>> >>                             <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
>> >>                             <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
>> >>                         <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
>> >>                     <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>
>> >>                 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>
>> >>             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>
>> >>     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