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

Braeden Profile jhaezhyr12 at gmail.com
Tue Oct 11 16:42:24 CDT 2016


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

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20161011/e8732b90/attachment.html>


More information about the swift-evolution mailing list