{"action":"created","issue":{"url":"https://api.github.com/repos/JuliaLang/julia/issues/18285","repository_url":"https://api.github.com/repos/JuliaLang/julia","labels_url":"https://api.github.com/repos/JuliaLang/julia/issues/18285/labels{/name}","comments_url":"https://api.github.com/repos/JuliaLang/julia/issues/18285/comments","events_url":"https://api.github.com/repos/JuliaLang/julia/issues/18285/events","html_url":"https://github.com/JuliaLang/julia/issues/18285","id":173920441,"number":18285,"title":"A case/switch statement for Julia","user":{"login":"bpr","id":351317,"avatar_url":"https://avatars.githubusercontent.com/u/351317?v=3","gravatar_id":"","url":"https://api.github.com/users/bpr","html_url":"https://github.com/bpr","followers_url":"https://api.github.com/users/bpr/followers","following_url":"https://api.github.com/users/bpr/following{/other_user}","gists_url":"https://api.github.com/users/bpr/gists{/gist_id}","starred_url":"https://api.github.com/users/bpr/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/bpr/subscriptions","organizations_url":"https://api.github.com/users/bpr/orgs","repos_url":"https://api.github.com/users/bpr/repos","events_url":"https://api.github.com/users/bpr/events{/privacy}","received_events_url":"https://api.github.com/users/bpr/received_events","type":"User","site_admin":false},"labels":[],"state":"closed","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":6,"created_at":"2016-08-30T03:11:38Z","updated_at":"2016-08-30T09:56:52Z","closed_at":"2016-08-30T07:07:24Z","body":"# Proposal\r\n\r\nJulia lacks a C-style [switch](http://en.wikipedia.org/wiki/Switch_statement) statement. This issue has [come up](https://github.com/JuliaLang/julia/issues/5410) [before](https://groups.google.com/forum/#!topic/julia-users/pnEqF5w4GJY/discussion) on various fora. Unsurprisingly, Julia also lacks [pattern matching](https://en.wikipedia.org/wiki/Pattern_matching), a useful generalization of case and switch, which has been implemented as a [macro](https://github.com/kmsquire/Match.jl) for Julia.\r\n\r\nThis proposal is concerned with using switch statements over integral (isbits) types  to exploit the ability of LLVM's [switch instruction](http://llvm.org/docs/LangRef.html#switch-instruction) to provide a [branch table](https://en.wikipedia.org/wiki/Branch_table) implementation of switch, which is more performant than a sequence of `if-else` conditionals. It should be amenable to supporting extended switch and pattern capabilities in the future; for that reason I'll suggest using adding the `case` keyword to introduce the form. If it's desired that the statement only be used as a C style switch and that pattern matching be introduced separately, perhaps `switch` is the better choice.\r\n\r\nI'll skip the arguments in around whether to include such a feature at all; interested readers can review some of those arguments in the context of [Python](http://www.python.org/dev/peps/pep-3103/) or [Lua](http://lua-users.org/wiki/SwitchStatement), as the arguments on both sides would be similar for Julia.\r\n\r\n# Syntax\r\n\r\nIf we'd like to subsume this in a future pattern matching Julia extension, I suggest a syntax influenced by the [Match.jl](https://github.com/kmsquire/Match.jl) macro, replacing `@match` with the keyword `case`, and adding a new keyword `of` to use instead of `begin`. I chose `of` because that's used in many other languages that use `case`, and because Julia constructs like `if/for/while` don't require a `begin` for their `end`.\r\n\r\n```Erlang\r\ncase case_expr of\r\n    case0 => expr0\r\n    case1 => expr1\r\n    .\r\n    .\r\n    .\r\n    caseNMinusOne => exprNMinusOne\r\n    else => exprN\r\nend\r\n```\r\n\r\nThe optional `else` at the end could be replaced by `_` or even `otherwise` or `default`, at the cost of using more keywords.\r\n\r\nEach case above could be preceded by an `of` if that syntax is preferable. It strikes me as a little wordy but it's a syntax used in other languages and perhaps people find it more readable.\r\n\r\n```Erlang\r\ncase case_expr\r\n    of case0 => expr0\r\n    of case1 => expr1\r\n    .\r\n    .\r\n    .\r\n    of caseNMinusOne => exprNMinusOne\r\n    else => exprN\r\nend\r\n```\r\n\r\n\r\n# Examples\r\n```Erlang\r\nn = rand(0:32)\r\nfunction print_if_lt_3(n)\r\n    case n of\r\n        0 => println(\"zero\")\r\n        1 => println(\"one\")\r\n        2 => println(\"two\")\r\n        else => println(\"too big\")\r\n    end\r\nend\r\n```\r\n\r\nShould be semantically equivalent to\r\n\r\n```Julia\r\nn = rand(0:32)\r\nfunction print_if_lt_3(n)\r\n    if n == 0 \r\n        println(\"zero\")\r\n    elseif n == 1\r\n        println(\"one\")\r\n    elseif n == 2\r\n        println(\"two\")\r\n    else\r\n        println(\"too big\")\r\n    end\r\nend\r\n```\r\n\r\nAn example with enums\r\n\r\n```Erlang\r\n@enum Dir north northeast east southeast south southwest west northwest\r\nfunction degree_of_dir(d)\r\n    case d of\r\n        north => 90\r\n        northeast => 45\r\n        east => 0\r\n        southeast => 315\r\n        south => 270\r\n        southwest => 225\r\n        west => 180\r\n        northwest => 135\r\n    end\r\nend\r\n```\r\n\r\nThe intent is that `@enum` should work well with this `case` statement, which means that the conversion to the enum's Int value should be implicit, as above.\r\n"},"comment":{"url":"https://api.github.com/repos/JuliaLang/julia/issues/comments/243391407","html_url":"https://github.com/JuliaLang/julia/issues/18285#issuecomment-243391407","issue_url":"https://api.github.com/repos/JuliaLang/julia/issues/18285","id":243391407,"user":{"login":"yuyichao","id":712232,"avatar_url":"https://avatars.githubusercontent.com/u/712232?v=3","gravatar_id":"","url":"https://api.github.com/users/yuyichao","html_url":"https://github.com/yuyichao","followers_url":"https://api.github.com/users/yuyichao/followers","following_url":"https://api.github.com/users/yuyichao/following{/other_user}","gists_url":"https://api.github.com/users/yuyichao/gists{/gist_id}","starred_url":"https://api.github.com/users/yuyichao/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/yuyichao/subscriptions","organizations_url":"https://api.github.com/users/yuyichao/orgs","repos_url":"https://api.github.com/users/yuyichao/repos","events_url":"https://api.github.com/users/yuyichao/events{/privacy}","received_events_url":"https://api.github.com/users/yuyichao/received_events","type":"User","site_admin":false},"created_at":"2016-08-30T09:56:52Z","updated_at":"2016-08-30T09:56:52Z","body":"As @timholy said, the proposal here also doesn't address, IMHO, the most important issue for #5410, i.e. how should this be related to LLVM `switch` instruction.\r\n\r\nThe LLVM `switch` instruction / C `switch` statement is really limited in terms of what is acceptable as the target value (constants), which is much more restricted than what's usually presented in high level languages AFAIK. Since the proposal mentions that\r\n\r\n> It should be amenable to supporting extended switch and pattern capabilities in the future\r\n\r\nI expect that the julia `switch` statement proposed here shouldn't have the LLVM restriction and it'll have to be purely a syntax sugar for a list of `if` as already provided by packages using macros and the lowering to LLVM switch statement has to be done via optimization and it doesn't matter if we have a special syntax or not. I'll be a little surprised if LLVM doesn't already have a pass to do this.\r\n\r\nAlso worth noting that\r\n\r\n> Julia lacks a C-style switch statement. This issue has come up before on various fora. Unsurprisingly, Julia also lacks pattern matching, a useful generalization of case and switch, which has been implemented as a macro for Julia.\r\n\r\nIsn't accurate. The syntax can be / is already implemented nicely as macros and unless there's something we can't do with macros, e.g. if we want to have special lowering for it (directly to a switch statement with LLVM restriction) or if we want to allow special handling at surface syntax level (like `@simd/@thread/@parallel for`), we don't really need to give it a special syntax.\r\n"}}
{"actor":{"display_login":"yuyichao"}}