Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[SR-37] RawRepresentable enum types should be auto unpacked. #42660

Open
swift-ci opened this issue Dec 4, 2015 · 8 comments
Open

[SR-37] RawRepresentable enum types should be auto unpacked. #42660

swift-ci opened this issue Dec 4, 2015 · 8 comments
Labels
compiler The Swift compiler in itself feature A feature request or implementation

Comments

@swift-ci
Copy link
Collaborator

swift-ci commented Dec 4, 2015

Previous ID SR-37
Radar None
Original Reporter blach (JIRA User)
Type Improvement
Additional Detail from JIRA
Votes 1
Component/s
Labels Improvement
Assignee None
Priority Medium

md5: 821bcb1fe2c1f28e6ac53d7cfb2e0ad6

relates to:

  • SR-3177 Should @objc enums be bridged to Objective-C as their raw value?

Issue Description:

In many cases it seems most natural to store application level constants in an enum. For instance:

enum Constants {
    enum Notifications {
        case LoggedIn
        case LoggedOut
    }
}

As one would expect (and as of Swift 2) you can now

print(Constants.Notifications.LoggedOut) // "LoggedOut"

This is because of the addition of the CustomStringConvertable protocol. However in similar situations where one might want to pass an enum as it's raw representation, it fails:

NSNotificationCenter.defaultCenter().postNotificationName(Constants.Notifications.LoggedOut, object: nil, userInfo: nil) // Can not convert 'Constants.Notifications.LoggedOut' to type 'String'

This seems counter intuitive. Especially in the case of an enum with an explicitly typed raw value (e.g. enum Notifications: String). This has lead to a plethora of work arounds. Here are three:

// 1
extension NSNotificationCenter {
    func postNotificationName(name: Constants.Notifications, object anObject: AnyObject?, userInfo aUserInfo: [NSObject : AnyObject]? = nil) {
        self.postNotificationName(name.rawValue, object: anObject, userInfo: aUserInfo)
    }
}

// 2
extension NSNotificationCenter {
    func postNotificationName<T: RawRepresentable where T.RawValue == String>(name: T, object anObject: AnyObject?, userInfo aUserInfo: [NSObject : AnyObject]? = nil) {
        self.postNotificationName(name.rawValue, object: anObject, userInfo: aUserInfo)
    }
}

// 3 
https://gist.github.com/designatednerd/5645d286df0ce939714b

// I really don't get the trouble that this last person went to, because it doesn't yield anything you'd actually want to use, but oh well.

In light of this, RawRepresentable types logically should map to their raw values when passed as arguments of that specified types, such that a simple

@lilyball
Copy link
Mannequin

lilyball mannequin commented Dec 4, 2015

Respectfully, I disagree. Swift errs on the side of requiring explicit type conversions in most cases that aren't upcasts (the biggest exception being bridging Swift types to obj-c). I don't like treating the enum like it was a string. If you actually want them to be strings, you could say something like

struct Constants {
    struct Notifications {
        static let LoggedIn = "LoggedIn"
        static let LoggedOut = "LoggedOut"
    }
}

Furthermore, this suggestion seems like something that should be posted to the swift-evolution list instead of here.

@swift-ci
Copy link
Collaborator Author

swift-ci commented Dec 4, 2015

Comment by Ben Lachman (JIRA)

I believe this would be an acceptable heuristic as well, however it doesn't work either. It still forces the developer to append the unsightly and no more clear .rawValue onto every enum. Additionally, Swift has already moved in the direction of enum's as strings with the adherence to (I believe) CustomStringConvertible (assumedly mostly for ease of debugging via print() as in my example and the like).

I think you're right that this might be more appropriate for swift-evolution… anyone else have an opinion?

@lilyball
Copy link
Mannequin

lilyball mannequin commented Dec 4, 2015

CustomStringConvertible does not mean that the value can be used as a string. It just means that the value can be printed. Notably, CustomStringConvertible says nothing about whether the string representation is actually meaningful. You may as well say that Swift has moved in the direction of integers as strings because Int conforms to CustomStringConvertible, and I hope it's obvious why that's not correct.

@belkadan
Copy link
Contributor

belkadan commented Dec 8, 2015

Yes, this would need to go through discussion on swift-evolution.

@swift-ci
Copy link
Collaborator Author

swift-ci commented Mar 2, 2017

Comment by Raphael (JIRA)

I agree. Philosophical discourse aside, declaring `enum A: String` and then having to `rawValue` everywhere you want to use the single, constant string represented by a case of this enum is just silly.

I think, though, that we should talk about auto-unpacking all RawRepresentables.

@swift-ci
Copy link
Collaborator Author

swift-ci commented Jul 6, 2017

Comment by Raphael (JIRA)

Today, this related issue confused me:

@belkadan
Copy link
Contributor

belkadan commented Jul 6, 2017

That's different enough to be worth a separate issue. I'm not sure that's at all "obvious", though, since the normal stringification of enum cases includes their names.

@swift-ci
Copy link
Collaborator Author

swift-ci commented Jul 6, 2017

Comment by Raphael (JIRA)

Yup, that's why I put it in a comment here: if RawRepresentable enums would act like their raw type, it would make sense to life more than just hashValue.

@swift-ci swift-ci transferred this issue from apple/swift-issues Apr 25, 2022
@AnthonyLatsis AnthonyLatsis added feature A feature request or implementation and removed new feature labels Jun 26, 2022
@AnthonyLatsis AnthonyLatsis added the compiler The Swift compiler in itself label Nov 7, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
compiler The Swift compiler in itself feature A feature request or implementation
Projects
None yet
Development

No branches or pull requests

3 participants