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

Mateusz Malczak mateusz at malczak.info
Tue Oct 11 17:13:21 CDT 2016


That's exactly what this proposal is about. I would like to
keep all enum properties but add an extra feature, so that enums can
store some extra data.
--
| Mateusz Malczak
+-------------------------------
| mateusz at malczak.info
| http://malczak.info


2016-10-11 23:42 GMT+02:00 Braeden Profile <jhaezhyr12 at gmail.com>:
> So, just to recap, the proposed solution is to help enums expose associated
> values via properties, and is not to create enums that are open to extra
> unnamed cases (RectSize(width:0,height:10))?  What I see is that enums would
> still maintain their standing where an instance is just a selection of a
> finite number of options, possibly with data attached.  In proposal 1, we
> want some sort of syntax where this…
>
> enum RectSize
> {
>    let height:Int
>    let width:Int
>    case small(width: 30, height: 30)
>    case medium(width: 60, height: 60)
>    case large(width: 120, height: 120)
> }
>
> …is syntactically just like writing this…
>
> enum RectSize
> {
>    case small
>    case medium
>    case large
>    var height:Int
>    {
>       switch self
>       {
>          case .small: return 30
>          case .medium: return 60
>          case .large: return 90
>       }
>    }
>    let width:Int
>    {
>       switch self
>       {
>          case .small: return 30
>          case .medium: return 60
>          case .large: return 90
>       }
>    }
> }
>
> …right?  That way, you can write this:
>
> var size: RectSize = .small
> size.height == 30 // true
> size.rawValue // Error:  RectSizes has no property `rawValue`.
> size.height = 40 // Error:  `height` is immutable
> size = .medium
>
> I think we were also (separately) proposing to extend `rawValue` to take all
> kinds of statically known values, like structs or tuples.  Doing that would
> accomplish much of the same thing.
>
> Someone fact-check me here!  I really do think something like this would be
> a good idea, if we could get the right syntax.
>
> On Oct 11, 2016, at 7:06 AM, Mateusz Malczak via swift-evolution
> <swift-evolution at swift.org> wrote:
>
> Hi,
> 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.
>
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
>
>


More information about the swift-evolution mailing list