Fixing raw enum types


(Anton Zhilin) #1

This idea by Karl made me branch off a new thread.

It would be helpful for synthesised RawRep conformance. The

inheritance-like syntax we have now is awful - it makes people think that
RawRepresentable is some kind of magic protocol that will allow special
compiler jango to happen.

You could see why they think that. This looks very much like the enum is
going to *be* an Int32:

enum Something: Int32 {
    case oneThing = 36
    case anotherThing = 42
}

This is also one of the icky parts to allowing tuples of integer/string
literals (something people ask for quite a lot). It would look like you’re
deriving your enum from a non-nominal type:

enum Something: (Int32, Int32) {
    case oneThing = (3, 12)
    case anotherThing = (5, 9)
}

Even if Swift gains newtype, it’s not that case. The enum does not gain

methods or behavior of the specified type. It’s just a shorthand, hinting
the compiler to provide correct RawRepresentable conformance.

I suggest to invent a new syntax for this type hinting for RawRepresentable.
For example, it can be an annotation:

@raw(Int32) enum Something {
    // ...
}

Or a contextual keyword:

enum Something : raw(Int32) {
    // ...
}

Perhaps, he most uniform and explicit of syntaxes:

enum Something : RawRepresentable {
    case oneThing = 36
    case anotherThing = 42
}

enum AnotherThing : RawRepresentable {
    typealias RawValue = Int32
    case oneThing
    case anotherThing
}

···

2017-01-16 21:28 GMT+03:00 Karl Wagner <razielim@gmail.com>:


(David Waite) #2

Or perhaps paint the bikeshed

enum Something<(Int32, Int32)> { … }

-DW

···

On Jan 16, 2017, at 11:51 AM, Anton Zhilin via swift-evolution <swift-evolution@swift.org> wrote:

This idea by Karl made me branch off a new thread.

2017-01-16 21:28 GMT+03:00 Karl Wagner <razielim@gmail.com <mailto:razielim@gmail.com>>:

It would be helpful for synthesised RawRep conformance. The inheritance-like syntax we have now is awful - it makes people think that RawRepresentable is some kind of magic protocol that will allow special compiler jango to happen.

You could see why they think that. This looks very much like the enum is going to *be* an Int32:

enum Something: Int32 {
    case oneThing = 36
    case anotherThing = 42
}

This is also one of the icky parts to allowing tuples of integer/string literals (something people ask for quite a lot). It would look like you’re deriving your enum from a non-nominal type:

enum Something: (Int32, Int32) {
    case oneThing = (3, 12)
    case anotherThing = (5, 9)
}

Even if Swift gains newtype, it’s not that case. The enum does not gain methods or behavior of the specified type. It’s just a shorthand, hinting the compiler to provide correct RawRepresentable conformance.

I suggest to invent a new syntax for this type hinting for RawRepresentable. For example, it can be an annotation:

@raw(Int32) enum Something {
    // ...
}
Or a contextual keyword:

enum Something : raw(Int32) {
    // ...
}
Perhaps, he most uniform and explicit of syntaxes:

enum Something : RawRepresentable {
    case oneThing = 36
    case anotherThing = 42
}

enum AnotherThing : RawRepresentable {
    typealias RawValue = Int32
    case oneThing
    case anotherThing
}
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(Derrick Ho) #3

enum Something: RawRepresentable<Int32> {

}

Generics?

···

On Mon, Jan 16, 2017 at 1:51 PM Anton Zhilin via swift-evolution < swift-evolution@swift.org> wrote:

This idea by Karl made me branch off a new thread.

2017-01-16 21:28 GMT+03:00 Karl Wagner <razielim@gmail.com>:

It would be helpful for synthesised RawRep conformance. The
inheritance-like syntax we have now is awful - it makes people think that
RawRepresentable is some kind of magic protocol that will allow special
compiler jango to happen.

You could see why they think that. This looks very much like the enum is
going to *be* an Int32:

enum Something: Int32 {
    case oneThing = 36
    case anotherThing = 42
}

This is also one of the icky parts to allowing tuples of integer/string
literals (something people ask for quite a lot). It would look like you’re
deriving your enum from a non-nominal type:

enum Something: (Int32, Int32) {
    case oneThing = (3, 12)
    case anotherThing = (5, 9)
}

Even if Swift gains newtype, it’s not that case. The enum does not gain
methods or behavior of the specified type. It’s just a shorthand, hinting
the compiler to provide correct RawRepresentable conformance.

I suggest to invent a new syntax for this type hinting for
RawRepresentable. For example, it can be an annotation:

@raw(Int32) enum Something {
    // ...
}

Or a contextual keyword:

enum Something : raw(Int32) {
    // ...
}

Perhaps, he most uniform and explicit of syntaxes:

enum Something : RawRepresentable {
    case oneThing = 36
    case anotherThing = 42
}

enum AnotherThing : RawRepresentable {
    typealias RawValue = Int32
    case oneThing
    case anotherThing
}


_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(Pranshu Goyal) #4

Definitely a +1, this clarifies intent, but enums are used a lot in swift
code, and considering this is a source breaking change I'm not sure if many
users of swift are going to be positive about this.

···

On 17 January 2017 at 02:32, David Waite via swift-evolution < swift-evolution@swift.org> wrote:

Or perhaps paint the bikeshed

enum Something<(Int32, Int32)> { … }

-DW

On Jan 16, 2017, at 11:51 AM, Anton Zhilin via swift-evolution < > swift-evolution@swift.org> wrote:

This idea by Karl made me branch off a new thread.

2017-01-16 21:28 GMT+03:00 Karl Wagner <razielim@gmail.com>:

It would be helpful for synthesised RawRep conformance. The

inheritance-like syntax we have now is awful - it makes people think that
RawRepresentable is some kind of magic protocol that will allow special
compiler jango to happen.

You could see why they think that. This looks very much like the enum is
going to *be* an Int32:

enum Something: Int32 {
    case oneThing = 36
    case anotherThing = 42
}

This is also one of the icky parts to allowing tuples of integer/string
literals (something people ask for quite a lot). It would look like you’re
deriving your enum from a non-nominal type:

enum Something: (Int32, Int32) {
    case oneThing = (3, 12)
    case anotherThing = (5, 9)
}

Even if Swift gains newtype, it’s not that case. The enum does not gain
methods or behavior of the specified type. It’s just a shorthand, hinting
the compiler to provide correct RawRepresentable conformance.

I suggest to invent a new syntax for this type hinting for
RawRepresentable. For example, it can be an annotation:

@raw(Int32) enum Something {
    // ...
}

Or a contextual keyword:

enum Something : raw(Int32) {
    // ...
}

Perhaps, he most uniform and explicit of syntaxes:

enum Something : RawRepresentable {
    case oneThing = 36
    case anotherThing = 42
}

enum AnotherThing : RawRepresentable {
    typealias RawValue = Int32
    case oneThing
    case anotherThing
}


_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

--
*Pranshu Goyal*


(Goffredo Marocchi) #5

Now is still the time for source breaking changes if well motivated, when dealing with key aspects of the language and we can make them objectively better then we ought to act when we can I think.

+1

···

Sent from my iPhone

On 17 Jan 2017, at 06:11, Pranshu Goyal via swift-evolution <swift-evolution@swift.org> wrote:

Definitely a +1, this clarifies intent, but enums are used a lot in swift code, and considering this is a source breaking change I'm not sure if many users of swift are going to be positive about this.

On 17 January 2017 at 02:32, David Waite via swift-evolution <swift-evolution@swift.org> wrote:
Or perhaps paint the bikeshed

enum Something<(Int32, Int32)> { … }

-DW

On Jan 16, 2017, at 11:51 AM, Anton Zhilin via swift-evolution <swift-evolution@swift.org> wrote:

This idea by Karl made me branch off a new thread.

2017-01-16 21:28 GMT+03:00 Karl Wagner <razielim@gmail.com>:

It would be helpful for synthesised RawRep conformance. The inheritance-like syntax we have now is awful - it makes people think that RawRepresentable is some kind of magic protocol that will allow special compiler jango to happen.

You could see why they think that. This looks very much like the enum is going to *be* an Int32:

enum Something: Int32 {
    case oneThing = 36
    case anotherThing = 42
}

This is also one of the icky parts to allowing tuples of integer/string literals (something people ask for quite a lot). It would look like you’re deriving your enum from a non-nominal type:

enum Something: (Int32, Int32) {
    case oneThing = (3, 12)
    case anotherThing = (5, 9)
}

Even if Swift gains newtype, it’s not that case. The enum does not gain methods or behavior of the specified type. It’s just a shorthand, hinting the compiler to provide correct RawRepresentable conformance.

I suggest to invent a new syntax for this type hinting for RawRepresentable. For example, it can be an annotation:

@raw(Int32) enum Something {
    // ...
}
Or a contextual keyword:

enum Something : raw(Int32) {
    // ...
}
Perhaps, he most uniform and explicit of syntaxes:

enum Something : RawRepresentable {
    case oneThing = 36
    case anotherThing = 42
}

enum AnotherThing : RawRepresentable {
    typealias RawValue = Int32
    case oneThing
    case anotherThing
}
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

--
Pranshu Goyal
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(Anton Zhilin) #6

Some criticism for all the mentioned variants:

enum Something : raw(Int32)
Requires adding a new contextual keyword.

enum Something : RawRepresentable
With additional typealias RawValue, the simplest cases will lose their
elegancy.

enum Something : RawRepresentable<Int32>
+1. But we don’t have generic protocols right now :frowning:

enum Something<Int32>
-1. This way we would just trade overloading conformance syntax for
overloading generics syntax.


(Joe Groff) #7

I think this would be the right direction to go if we wanted to de-magic the existing RawRepresentable behavior. At this point, It would be reasonable to support this via where clauses on associated types:

enum Something: RawRepresentable where RawValue == Int32 { ... }

though that's pretty verbose. In the fullness of time, a generic typealias to a generalized existential could help with that, though:

typealias RawRepresentableOf<T> = RawRepresentable where RawValue == T

At that point, the compiler-built becomes closer to just a "regular" default implementation. There's still the privileged sugar for matching cases to raw values.

-Joe

···

On Jan 17, 2017, at 9:54 AM, Anton Zhilin via swift-evolution <swift-evolution@swift.org> wrote:

Some criticism for all the mentioned variants:

enum Something : raw(Int32)
Requires adding a new contextual keyword.

enum Something : RawRepresentable
With additional typealias RawValue, the simplest cases will lose their elegancy.

enum Something : RawRepresentable<Int32>
+1. But we don’t have generic protocols right now :frowning:


(Haravikk) #8

While I like the idea of RawRepresentable<Int32>, the use of an associatetype seems like the most obvious choice, as it's consistent with other types.
I'm not sure I'd agree that it loses elegance, especially if we can get type inference, for example:

  enum Something : RawRepresentable { case .Foo = 1, .Bar = 2 }

Would be equivalent to:

  enum Something : RawRepresentable {
    typealias RawType = Int
    case .Foo = 1
    case .Bar = 2
  }

Just the same as any other type inference really. We could even have the RawRepresentable conformance inferred (so you don't have to specify it if you set raw values).

···

On 17 Jan 2017, at 17:54, Anton Zhilin via swift-evolution <swift-evolution@swift.org> wrote:
enum Something : RawRepresentable
With additional typealias RawValue, the simplest cases will lose their elegancy.


(Anton Zhilin) #9

enum Something : RawRepresentable<Int32>
+1. But we don’t have generic protocols right now :frowning:

I think this would be the right direction to go if we wanted to de-magic
the existing RawRepresentable behavior. At this point, It would be
reasonable to support this via where clauses on associated types:

enum Something: RawRepresentable where RawValue == Int32 { ... }

We don't have this conformance syntax either. As the enum is not generic,
the above should be read as:

    enum Something: (RawRepresentable where RawValue == Int32) { ... }

And this requires generalized existentials again.

though that's pretty verbose. In the fullness of time, a generic typealias

···

2017-01-17 22:26 GMT+03:00 Joe Groff <jgroff@apple.com>:

to a generalized existential could help with that, though:

typealias RawRepresentableOf<T> = RawRepresentable where RawValue == T

At that point, the compiler-built becomes closer to just a "regular"
default implementation. There's still the privileged sugar for matching
cases to raw values.

-Joe


(Joe Groff) #10

Sorry, I wasn't clear. We don't now, but in the fullness of time we should be able to support that.

-Joe

···

On Jan 17, 2017, at 1:12 PM, Anton Zhilin <antonyzhilin@gmail.com> wrote:

2017-01-17 22:26 GMT+03:00 Joe Groff <jgroff@apple.com <mailto:jgroff@apple.com>>:

enum Something : RawRepresentable<Int32>
+1. But we don’t have generic protocols right now :frowning:

I think this would be the right direction to go if we wanted to de-magic the existing RawRepresentable behavior. At this point, It would be reasonable to support this via where clauses on associated types:

enum Something: RawRepresentable where RawValue == Int32 { ... }

We don't have this conformance syntax either.