{"action":"created","issue":{"url":"https://api.github.com/repos/dotnet/csharplang/issues/176","repository_url":"https://api.github.com/repos/dotnet/csharplang","labels_url":"https://api.github.com/repos/dotnet/csharplang/issues/176/labels{/name}","comments_url":"https://api.github.com/repos/dotnet/csharplang/issues/176/comments","events_url":"https://api.github.com/repos/dotnet/csharplang/issues/176/events","html_url":"https://github.com/dotnet/csharplang/issues/176","id":210013227,"number":176,"title":"Proposal: return, break and continue expressions","user":{"login":"alrz","id":3105979,"avatar_url":"https://avatars1.githubusercontent.com/u/3105979?v=3","gravatar_id":"","url":"https://api.github.com/users/alrz","html_url":"https://github.com/alrz","followers_url":"https://api.github.com/users/alrz/followers","following_url":"https://api.github.com/users/alrz/following{/other_user}","gists_url":"https://api.github.com/users/alrz/gists{/gist_id}","starred_url":"https://api.github.com/users/alrz/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/alrz/subscriptions","organizations_url":"https://api.github.com/users/alrz/orgs","repos_url":"https://api.github.com/users/alrz/repos","events_url":"https://api.github.com/users/alrz/events{/privacy}","received_events_url":"https://api.github.com/users/alrz/received_events","type":"User","site_admin":false},"labels":[{"id":537024200,"url":"https://api.github.com/repos/dotnet/csharplang/labels/Discussion","name":"Discussion","color":"c2e0c6","default":false},{"id":545773793,"url":"https://api.github.com/repos/dotnet/csharplang/labels/Feature%20Request","name":"Feature Request","color":"d4c5f9","default":false}],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":24,"created_at":"2017-02-24T10:33:06Z","updated_at":"2017-06-24T16:24:05Z","closed_at":null,"body":"Ported from https://github.com/dotnet/roslyn/issues/14239\r\n\r\n# return, break and continue expressions\r\n\r\n## Summary\r\n\r\nLets you use `return`, `break` and `continue` as an expression.\r\n\r\n## Proposal\r\n\r\nSince `throw` is now an expression, I think `return` , `break` and `continue` are also good candidates to be an expression. \r\n\r\n``` cs\r\nvar c = obj as C ?? return;\r\n// instead of\r\nif(!(obj is C c)) return;\r\n\r\n\r\nvar o = F() ?? return;\r\n// instead of\r\nvar o = F();\r\nif (o == null) return;\r\n\r\nvar (foo, bar) = GetFooBar() ?? return; // `GetFooBar` returns a nullable tuple\r\n// instead of\r\nif (!(GetFooBar() is var (foo, bar))) return;\r\n// or\r\nif (!TryGetFooBar(out var foo, out var bar)) return;\r\n// or \r\nvar result = GetFooBar();\r\nif (result == null) return;\r\nvar (foo, bar) = result.Value;\r\n\r\nforeach (var item in list) {\r\n  var result = item match {\r\n    case 1: \"one\",\r\n    case 2: \"two\",\r\n    case 3: break,\r\n    default: continue,\r\n  };\r\n}\r\n```\r\n\r\nThere is no straightforward alternative for the third example as you will need to use the `switch` statement.\r\n\r\n\r\nNote that this could be allowed in the \"head\" of a loop, useful for early returns,\r\n```cs\r\nforeach (var item in list ?? break)\r\nforeach (var item in list ?? return)\r\n```\r\n**Open question:** would it make sense to allow `continue` in this context? (probably not)\r\n\r\nAnother use case is to detect if a loop went to the very end.\r\n```cs\r\nwhile (condition || return) {\r\n  if (...) break;\r\n}\r\n```\r\n**Open question:** `throw` expressions are not allowed as the RHS for `&&` and `||`. should that also be applied here?\r\n\r\n~~Unlike `throw`,  these expressions need to return a value,~~\r\n```cs\r\nvoid F(out int i, out int j) {\r\n  (i, j) = condition ? (1, 2) : return;\r\n}\r\n```\r\n**EDIT:** We could make this specific example an error  as suggested by @lostmsu. So semantically it would be identical to `throw` expressions.\r\n\r\n**Open question:** should we allow `yield break` and `goto` as an expression? (`yield return` is excluded because it is not a jump instruction).\r\n"},"comment":{"url":"https://api.github.com/repos/dotnet/csharplang/issues/comments/310848589","html_url":"https://github.com/dotnet/csharplang/issues/176#issuecomment-310848589","issue_url":"https://api.github.com/repos/dotnet/csharplang/issues/176","id":310848589,"user":{"login":"jnm2","id":8040367,"avatar_url":"https://avatars1.githubusercontent.com/u/8040367?v=3","gravatar_id":"","url":"https://api.github.com/users/jnm2","html_url":"https://github.com/jnm2","followers_url":"https://api.github.com/users/jnm2/followers","following_url":"https://api.github.com/users/jnm2/following{/other_user}","gists_url":"https://api.github.com/users/jnm2/gists{/gist_id}","starred_url":"https://api.github.com/users/jnm2/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jnm2/subscriptions","organizations_url":"https://api.github.com/users/jnm2/orgs","repos_url":"https://api.github.com/users/jnm2/repos","events_url":"https://api.github.com/users/jnm2/events{/privacy}","received_events_url":"https://api.github.com/users/jnm2/received_events","type":"User","site_admin":false},"created_at":"2017-06-24T16:24:05Z","updated_at":"2017-06-24T16:24:05Z","body":"@alrz Not the `DateTime` local, the `DateTime?` local."}}
{"actor":{"display_login":"jnm2"}}