{"action":"created","issue":{"url":"https://api.github.com/repos/golang/go/issues/22796","repository_url":"https://api.github.com/repos/golang/go","labels_url":"https://api.github.com/repos/golang/go/issues/22796/labels{/name}","comments_url":"https://api.github.com/repos/golang/go/issues/22796/comments","events_url":"https://api.github.com/repos/golang/go/issues/22796/events","html_url":"https://github.com/golang/go/issues/22796","id":275045152,"number":22796,"title":"proposal: Go2: add common way to handle operations safely","user":{"login":"hirochachacha","id":898442,"avatar_url":"https://avatars0.githubusercontent.com/u/898442?v=4","gravatar_id":"","url":"https://api.github.com/users/hirochachacha","html_url":"https://github.com/hirochachacha","followers_url":"https://api.github.com/users/hirochachacha/followers","following_url":"https://api.github.com/users/hirochachacha/following{/other_user}","gists_url":"https://api.github.com/users/hirochachacha/gists{/gist_id}","starred_url":"https://api.github.com/users/hirochachacha/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/hirochachacha/subscriptions","organizations_url":"https://api.github.com/users/hirochachacha/orgs","repos_url":"https://api.github.com/users/hirochachacha/repos","events_url":"https://api.github.com/users/hirochachacha/events{/privacy}","received_events_url":"https://api.github.com/users/hirochachacha/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":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":227,"closed_issues":349,"state":"open","created_at":"2015-10-24T01:40:49Z","updated_at":"2018-02-03T16:19:57Z","due_on":null,"closed_at":null},"comments":20,"created_at":"2017-11-18T02:14:34Z","updated_at":"2018-02-03T23:48:06Z","closed_at":null,"author_association":"CONTRIBUTOR","body":"Currently, map access and type assertions have way to detect unsafe operations before causing runtime panic.\r\nI propose extending the syntax for all operations that may cause runtime panic.\r\n\r\n# Proposal\r\n\r\n* index access\r\n```\r\nif x, ok := a[n]; ok {\r\n\t...\r\n}\r\n```\r\nis equivalent to \r\n```\r\nif 0 <= n && n < len(a) {\r\n\tx := a[n]\r\n\t...\r\n}\r\n```\r\n\r\n* slicing / full slicing\r\n```\r\nif x, ok := a[n:m]; ok {\r\n\t...\r\n}\r\n\r\nif x, ok := a[n:m:max]; ok {\r\n\t...\r\n}\r\n```\r\nis equivalent to \r\n```\r\nif 0 <= n && n <= m && m <= len(a) { // use cap(a) for slices\r\n\tx := a[n:m]\r\n\t...\r\n}\r\n\r\nif 0 <= n && n <= m && m <= max && max <= cap(a) {\r\n\tx := a[n:m:max]\r\n\t...\r\n}\r\n```\r\n\r\n* pointer access\r\n```\r\nif foo, ok := p.Foo; ok {\r\n\t...\r\n}\r\n```\r\nis equivalent to \r\n```\r\nif p != nil {\r\n\tfoo := p.Foo\r\n\t...\r\n}\r\n```\r\n* integer division\r\n```\r\nif z, ok := x/y; ok {\r\n\t...\r\n}\r\n```\r\nis equivalent to\r\n```\r\nif y != 0 {\r\n\tz := x/y\r\n\t...\r\n}\r\n```\r\n\r\n* pointer dereference\r\n```\r\nif x, ok := *p; ok {\r\n\t...\r\n}\r\n```\r\nis equivalent to\r\n```\r\nif p != nil {\r\n\tx := *p\r\n\t...\r\n}\r\n```\r\n\r\n* dynamic type comparison\r\n```\r\nif b, ok := iface1 == iface2; ok {\r\n\t...\r\n}\r\n```\r\nno equivalent syntax now.\r\n\r\n\r\nAfter defining above semantics, we can define another one.\r\n\r\n* deep checking\r\n```\r\nif s, ok := out[0].Left.Orig.Sym.Name[:1]; ok && s != \"~r\" { // ~r%d is the name invented for an unnamed result\r\n\t...\r\n}\r\n```\r\nis equivalent to\r\n```\r\n// taken from cmd/compile/internal/gc/dcl.go\r\n\r\nif len(out) > 0 && out[0].Left != nil && out[0].Left.Orig != nil {\r\n\ts := out[0].Left.Orig.Sym\r\n\tif s != nil && (s.Name[0] != '~' || s.Name[1] != 'r') { // ~r%d is the name invented for an unnamed result\r\n\t\t...\r\n\t}\r\n}\r\n```\r\n\r\n# Motivation\r\n\r\nI think 'deep checking' example explains the situation.\r\nTo write correct code, to review somebody's code, \r\nWe have to consider array/slice bounds check, null check, ..., etc.\r\nThose boilerplate are verbose and error prone still today.\r\nThe only important question for this kind of problem is 'Is the target attribute accessible or not?'.\r\nThe new semantics answer that question clearly without any noise.\r\nWe can guarantee that code works as intended without knowing details.\r\n\r\nThank you for reading."},"comment":{"url":"https://api.github.com/repos/golang/go/issues/comments/362866797","html_url":"https://github.com/golang/go/issues/22796#issuecomment-362866797","issue_url":"https://api.github.com/repos/golang/go/issues/22796","id":362866797,"user":{"login":"nhooyr","id":10180857,"avatar_url":"https://avatars1.githubusercontent.com/u/10180857?v=4","gravatar_id":"","url":"https://api.github.com/users/nhooyr","html_url":"https://github.com/nhooyr","followers_url":"https://api.github.com/users/nhooyr/followers","following_url":"https://api.github.com/users/nhooyr/following{/other_user}","gists_url":"https://api.github.com/users/nhooyr/gists{/gist_id}","starred_url":"https://api.github.com/users/nhooyr/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/nhooyr/subscriptions","organizations_url":"https://api.github.com/users/nhooyr/orgs","repos_url":"https://api.github.com/users/nhooyr/repos","events_url":"https://api.github.com/users/nhooyr/events{/privacy}","received_events_url":"https://api.github.com/users/nhooyr/received_events","type":"User","site_admin":false},"created_at":"2018-02-03T23:48:06Z","updated_at":"2018-02-03T23:48:06Z","author_association":"CONTRIBUTOR","body":"Huh, TIL. Thanks!"}}
{"actor":{"display_login":"nhooyr"}}