[swift-evolution] [Proposal] Enums with stored properties
Rien
Rien at Balancingrock.nl
Wed Oct 12 01:42:59 CDT 2016
I’d give a +1 for the suggestion of Braeden.
Mateusz, you lost me with “store some extra data”.
Does that mean something extra besides the code that Braeden suggested?
Rien.
> On 12 Oct 2016, at 00:13, Mateusz Malczak via swift-evolution <swift-evolution at swift.org> wrote:
>
> 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
>>
>>
> _______________________________________________
> 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