[swift-evolution] [Proposal] Enums with stored properties

Mateusz Malczak mateusz at malczak.info
Tue Oct 11 08:06:05 CDT 2016

I think we are here discussing two different aspects of introducing
this new feature - code syntax and underlying implementation.
In terms of code syntax I would go with first proposal as it seems to
me the simplest approach. When it comes to underlying implementation,
I can imagine that during compilation internal struct is created, as
well as any required property getters. This way you could get a
variation of rawValue implementation, at least from theoretical point
of view :D

| Mateusz Malczak
| mateusz at malczak.info
| http://malczak.info

2016-10-10 23:42 GMT+02:00 Haravikk <swift-evolution at haravikk.me>:
> On 10 Oct 2016, at 20:34, Mateusz Malczak <mateusz at malczak.info> wrote:
> I know, but what I'm saying is that this problem could be solved in the
> multiple values case by allowing tuples as raw values for enums, since that
> would allow you to specify both width and height. So it'd look something
> like this:
> We have three different possible solution
> 1. stored properties defined as part of enumeration type
> enum RectSizes: MyRect
> {
>    let height:Int
>    let width:Int
>    case Small(width: 30, height: 30)
>    case Medium(width: 60, height: 60)
>    case Large(width: 120, height: 120)
> }
> 2. struct as rawValue
> struct MyRect
> {
>    var height:Int
>    var width:Int
>    var area:Int {return height:Int*width}
> }
> enum RectSizes: MyRect
> {
>    case Small(30,30)
>    case Medium(60,60)
>    case Large(120,120)
> }
> 3. tuples as rawValue
> enum Format : (width:Int, height:Int) {
>    case small(30, 30)
>    case medium(60, 60)
>    case large(120, 120)
>    var width:Int { return self.rawValue.width }
>    var height:Int { return self.rawValue.height }
> }
> Solutions 2 and 3 are quire similar, to get value of a stored property
> we need to use rawValue or define value getters. In addition in
> solution 2 we define an additional data type just to be used as an
> enumeration type rawValue type. In my opinion, first approach would be
> a best solution, type definition is clear and self-explanatory because
> it is similar to how enums/classes are defined.
> --
> | Mateusz Malczak
> Actually I'd say your option 2 here is more similar to option 1 (you seem to
> be using a struct to define the stored properties instead). The issue here
> is that storing properties conflicts with what you're actually doing, which
> is storing case-specific values, which is what rawValue already does, it's
> just too limited for your current use-case (multiple values).
> The complete solution would be to introduce the concept of tuples as
> literals (even though they can't currently conform to types); this would
> make it a lot easier to support the use of any type as a fixed value for
> each case (not just tuples). For example, say we introduced as new protocol:
> protocol ExpressableByTuple {
> associatedtype TupleType // somehow force this to be a tuple or
> ExpressableByType type
> init(tupleLiteral:TupleType)
> }
> With a bit of magic all tuples could conform to this protocol with
> themselves as the literal type, allowing us to use them as enum raw values;
> likewise this could then be used to more easily enable any custom
> struct/class for storage in enum cases, as instead of supporting their
> constructors directly we can just support construction via a tuple literal.
> My other reason I don't favour option 1, while it looks a bit prettier, is
> that it's a bit confusing; enums have two types of stored properties, ones
> that can be changed (and inspected) which is what you get when you declare
> case small(Int, Int) for example, these are stored as part of the enum
> itself (so in that example it's 17-bytes on a 64-bit system). However
> rawValues are more like constants/static values, and don't increase the size
> of the type, and I just feel that this is the right way to do what you're
> proposing.

More information about the swift-evolution mailing list