{"action":"created","issue":{"url":"https://api.github.com/repos/golang/go/issues/19814","repository_url":"https://api.github.com/repos/golang/go","labels_url":"https://api.github.com/repos/golang/go/issues/19814/labels{/name}","comments_url":"https://api.github.com/repos/golang/go/issues/19814/comments","events_url":"https://api.github.com/repos/golang/go/issues/19814/events","html_url":"https://github.com/golang/go/issues/19814","id":218638547,"number":19814,"title":"proposal: spec: add typed enum support","user":{"login":"derekperkins","id":3588778,"avatar_url":"https://avatars0.githubusercontent.com/u/3588778?v=4","gravatar_id":"","url":"https://api.github.com/users/derekperkins","html_url":"https://github.com/derekperkins","followers_url":"https://api.github.com/users/derekperkins/followers","following_url":"https://api.github.com/users/derekperkins/following{/other_user}","gists_url":"https://api.github.com/users/derekperkins/gists{/gist_id}","starred_url":"https://api.github.com/users/derekperkins/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/derekperkins/subscriptions","organizations_url":"https://api.github.com/users/derekperkins/orgs","repos_url":"https://api.github.com/users/derekperkins/repos","events_url":"https://api.github.com/users/derekperkins/events{/privacy}","received_events_url":"https://api.github.com/users/derekperkins/received_events","type":"User","site_admin":false},"labels":[{"id":150880249,"url":"https://api.github.com/repos/golang/go/labels/Go2","name":"Go2","color":"ffaaaa","default":false},{"id":150880200,"url":"https://api.github.com/repos/golang/go/labels/LanguageChange","name":"LanguageChange","color":"ffaaaa","default":false},{"id":373402289,"url":"https://api.github.com/repos/golang/go/labels/NeedsInvestigation","name":"NeedsInvestigation","color":"ededed","default":false},{"id":236419512,"url":"https://api.github.com/repos/golang/go/labels/Proposal","name":"Proposal","color":"ededed","default":false}],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":{"url":"https://api.github.com/repos/golang/go/milestones/30","html_url":"https://github.com/golang/go/milestone/30","labels_url":"https://api.github.com/repos/golang/go/milestones/30/labels","id":1373555,"number":30,"title":"Proposal","description":"Proposals that are pending (not yet accepted/rejected).\r\n","creator":{"login":"rsc","id":104030,"avatar_url":"https://avatars1.githubusercontent.com/u/104030?v=4","gravatar_id":"","url":"https://api.github.com/users/rsc","html_url":"https://github.com/rsc","followers_url":"https://api.github.com/users/rsc/followers","following_url":"https://api.github.com/users/rsc/following{/other_user}","gists_url":"https://api.github.com/users/rsc/gists{/gist_id}","starred_url":"https://api.github.com/users/rsc/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/rsc/subscriptions","organizations_url":"https://api.github.com/users/rsc/orgs","repos_url":"https://api.github.com/users/rsc/repos","events_url":"https://api.github.com/users/rsc/events{/privacy}","received_events_url":"https://api.github.com/users/rsc/received_events","type":"User","site_admin":false},"open_issues":185,"closed_issues":497,"state":"open","created_at":"2015-10-24T01:40:49Z","updated_at":"2018-05-14T21:19:53Z","due_on":null,"closed_at":null},"comments":137,"created_at":"2017-03-31T23:07:08Z","updated_at":"2018-05-15T00:56:18Z","closed_at":null,"author_association":"NONE","body":"I'd like to propose that enum be added to Go as a special kind of `type`. The examples below are borrowed from the protobuf example.\r\n\r\n### Enums in Go today\r\n```\r\ntype SearchRequest int\r\nvar (\r\n\tSearchRequestUNIVERSAL SearchRequest = 0 // UNIVERSAL\r\n\tSearchRequestWEB       SearchRequest = 1 // WEB\r\n\tSearchRequestIMAGES    SearchRequest = 2 // IMAGES\r\n\tSearchRequestLOCAL     SearchRequest = 3 // LOCAL\r\n\tSearchRequestNEWS      SearchRequest = 4 // NEWS\r\n\tSearchRequestPRODUCTS  SearchRequest = 5 // PRODUCTS\r\n\tSearchRequestVIDEO     SearchRequest = 6 // VIDEO\r\n)\r\n\r\ntype SearchRequest string\r\nvar (\r\n\tSearchRequestUNIVERSAL SearchRequest = \"UNIVERSAL\"\r\n\tSearchRequestWEB       SearchRequest = \"WEB\"\r\n\tSearchRequestIMAGES    SearchRequest = \"IMAGES\"\r\n\tSearchRequestLOCAL     SearchRequest = \"LOCAL\"\r\n\tSearchRequestNEWS      SearchRequest = \"NEWS\"\r\n\tSearchRequestPRODUCTS  SearchRequest = \"PRODUCTS\"\r\n\tSearchRequestVIDEO     SearchRequest = \"VIDEO\"\r\n)\r\n\r\n// IsValid has to be called everywhere input happens, or you risk bad data - no guarantees\r\nfunc (sr SearchRequest) IsValid() bool {\r\n\tswitch sr {\r\n\t\tcase SearchRequestUNIVERSAL, SearchRequestWEB...:\r\n\t\t\treturn true\r\n\t}\r\n\treturn false\r\n}\r\n```\r\n\r\n### How it might look with language support\r\n```\r\nenum SearchRequest int {\r\n    0 // UNIVERSAL\r\n    1 // WEB\r\n    2 // IMAGES\r\n    3 // LOCAL\r\n    4 // NEWS\r\n    5 // PRODUCTS\r\n    6 // VIDEO\r\n}\r\n\r\nenum SearchRequest string {\r\n    \"UNIVERSAL\"\r\n    \"WEB\"\r\n    \"IMAGES\"\r\n    \"LOCAL\"\r\n    \"NEWS\"\r\n    \"PRODUCTS\"\r\n    \"VIDEO\"\r\n}\r\n```\r\n\r\nThe pattern is common enough that I think it warrants special casing, and I believe that it makes code more readable. At the implementation layer, I would imagine that the majority of cases can be checked at compile time, some of which already happen today, while others are near impossible or require significant tradeoffs.\r\n - **Safety for exported types**: nothing prevents someone from doing `SearchRequest(99)` or `SearchRequest(\"MOBILEAPP\")`. Current workarounds include making an unexported type with options, but that often makes the resulting code harder to use / document.\r\n - **Runtime safety**: Just like protobuf is going to check for validity while unmarshaling, this provides language wide validation, anytime that an enum is instantiated.\r\n - **Tooling / Documentation**: many packages today put valid options into field comments, but not everyone does it and there is no guarantee that the comments aren't outdated.\r\n\r\n### Things to Consider\r\n - **Nil**: by implementing `enum` on top of the type system, I don't believe this should require special casing.  If someone wants `nil` to be valid, then the enum should be defined as a pointer.\r\n - **Default value / runtime assignments**: This is one of the tougher decisions to make. What if the Go default value isn't defined as a valid enum? Static analysis can mitigate some of this at compile time, but there would need to be a way to handle outside input.\r\n\r\nI don't have any strong opinions on the syntax. I do believe this could be done well and would make a positive impact on the ecosystem."},"comment":{"url":"https://api.github.com/repos/golang/go/issues/comments/389008303","html_url":"https://github.com/golang/go/issues/19814#issuecomment-389008303","issue_url":"https://api.github.com/repos/golang/go/issues/19814","id":389008303,"user":{"login":"ljeabmreosn","id":15353402,"avatar_url":"https://avatars1.githubusercontent.com/u/15353402?v=4","gravatar_id":"","url":"https://api.github.com/users/ljeabmreosn","html_url":"https://github.com/ljeabmreosn","followers_url":"https://api.github.com/users/ljeabmreosn/followers","following_url":"https://api.github.com/users/ljeabmreosn/following{/other_user}","gists_url":"https://api.github.com/users/ljeabmreosn/gists{/gist_id}","starred_url":"https://api.github.com/users/ljeabmreosn/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ljeabmreosn/subscriptions","organizations_url":"https://api.github.com/users/ljeabmreosn/orgs","repos_url":"https://api.github.com/users/ljeabmreosn/repos","events_url":"https://api.github.com/users/ljeabmreosn/events{/privacy}","received_events_url":"https://api.github.com/users/ljeabmreosn/received_events","type":"User","site_admin":false},"created_at":"2018-05-15T00:56:18Z","updated_at":"2018-05-15T00:56:18Z","author_association":"NONE","body":"@zerkms Yes, that is one possibility, but given the type of `d`, type inference should be possible; however, the qualified use of enums (as in your example) is a bit easier to read."}}
{"actor":{"display_login":"ljeabmreosn"}}