On 26.05.2016 23:03, Leonardo Pessoa 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.

At this moment I think your proposal for tuples as raw value for enum is the best. So we can ask just to support tuples(not other types, at least yet) as raw type and use tuple values directly on enum instance(without `.rawValue.`). The question is if this is doable and if there is a support for this in community and in core team. (even for post Swift 3.0 era) As I understand, for this we need implicit implementation of Equatable for tuple as raw value and probably of RawRepresentable.

>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.

As for dictionary. I don't think of it as implementation detail for static stored properties for each case. Such dictionary could be helpful in other situations when you need assign some value for each enum case in your code. *The main point* is a feature that compiler checks that value is assigned for *each* case.

For example, in your code you need to assign color for each case in Planets. You can do this in switch:

switch e {
  case .earth : color = colorA
  case .moon : color = colorB
}

but instead you can create a dict:
let planetToColor = [Planet.earth : colorA, .moon : colorB]
and use as planetToColor[e]!  // yes, have to use `!` here

But, this is *not safe*(but very handy and useful) - as if you *add* new case in enum (let's say .mars) you will not be notified(in opposite to switch) that your planetToColor must me changed also - it does not contain color for .mars. You will know about this only in runtime.

So, it will be very good for our code, if we have such dictionary which will check at compile time that all cases are presented as keys in it.


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.


There was "ValueEnumerable protocol with derived implementation for enums" thread in this mailing list, you can review discussion in it regarding "values()" feature.
I also wish someone create a proposal to improve enums in a number of ways.

---------------------------------------------------------------------------
From: Vladimir.S <mailto:[email protected]>
Sent: ‎26/‎05/‎2016 03:06 PM
To: Leonardo Pessoa <mailto:[email protected]>
Cc: swift-evolution <mailto:[email protected]>
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:[email protected]>
Sent: ‎26/‎05/‎2016 02:36 PM
To: Ross O'Brien <mailto:[email protected]>
Cc: swift-evolution <mailto:[email protected]>
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
<[email protected] <mailto:[email protected]>> 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
        <[email protected] <mailto:[email protected]>>
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
                        <[email protected]
                        <mailto:[email protected]>
                        <mailto:[email protected]
                        <mailto:[email protected]>>> wrote:


                            On May 25, 2016, at 10:27 PM, Jacob
                            Bandes-Storch <[email protected]
                            <mailto:[email protected]>
                            <mailto:[email protected]
                            <mailto:[email protected]>>> wrote:

                            On Wed, May 25, 2016 at 8:15 PM, David Sweeris
                            via swift-evolution
                            <[email protected]
                            <mailto:[email protected]>
                            <mailto:[email protected]
                            <mailto:[email protected]>>> wrote:

                                On May 25, 2016, at 7:37 AM, Leonardo
                            Pessoa via swift-evolution
                                <[email protected]
                            <mailto:[email protected]>
                            <mailto:[email protected]
                            <mailto:[email protected]>>>
                            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
                        [email protected]
                        <mailto:[email protected]>
                        <mailto:[email protected]
                        <mailto:[email protected]>>

https://lists.swift.org/mailman/listinfo/swift-evolution



                    _______________________________________________
                    swift-evolution mailing list
                    [email protected]
                    <mailto:[email protected]>
                    <mailto:[email protected]
                    <mailto:[email protected]>>
                    https://lists.swift.org/mailman/listinfo/swift-evolution





                _______________________________________________
                swift-evolution mailing list
                [email protected] <mailto:[email protected]>
                https://lists.swift.org/mailman/listinfo/swift-evolution

            _______________________________________________
            swift-evolution mailing list
            [email protected] <mailto:[email protected]>
            https://lists.swift.org/mailman/listinfo/swift-evolution


    _______________________________________________
    swift-evolution mailing list
    [email protected] <mailto:[email protected]>
    https://lists.swift.org/mailman/listinfo/swift-evolution


_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution
_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to