{"action":"created","issue":{"url":"https://api.github.com/repos/JuliaLang/julia/issues/24990","repository_url":"https://api.github.com/repos/JuliaLang/julia","labels_url":"https://api.github.com/repos/JuliaLang/julia/issues/24990/labels{/name}","comments_url":"https://api.github.com/repos/JuliaLang/julia/issues/24990/comments","events_url":"https://api.github.com/repos/JuliaLang/julia/issues/24990/events","html_url":"https://github.com/JuliaLang/julia/pull/24990","id":280587731,"node_id":"MDExOlB1bGxSZXF1ZXN0MTU3MzEyODI1","number":24990,"title":"RFC: curry underscore arguments to create anonymous functions","user":{"login":"stevengj","id":2913679,"node_id":"MDQ6VXNlcjI5MTM2Nzk=","avatar_url":"https://avatars3.githubusercontent.com/u/2913679?v=4","gravatar_id":"","url":"https://api.github.com/users/stevengj","html_url":"https://github.com/stevengj","followers_url":"https://api.github.com/users/stevengj/followers","following_url":"https://api.github.com/users/stevengj/following{/other_user}","gists_url":"https://api.github.com/users/stevengj/gists{/gist_id}","starred_url":"https://api.github.com/users/stevengj/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/stevengj/subscriptions","organizations_url":"https://api.github.com/users/stevengj/orgs","repos_url":"https://api.github.com/users/stevengj/repos","events_url":"https://api.github.com/users/stevengj/events{/privacy}","received_events_url":"https://api.github.com/users/stevengj/received_events","type":"User","site_admin":false},"labels":[{"id":210700,"node_id":"MDU6TGFiZWwyMTA3MDA=","url":"https://api.github.com/repos/JuliaLang/julia/labels/decision","name":"decision","color":"F08000","default":false},{"id":163368715,"node_id":"MDU6TGFiZWwxNjMzNjg3MTU=","url":"https://api.github.com/repos/JuliaLang/julia/labels/parser","name":"parser","color":"bfdadc","default":false}],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":{"url":"https://api.github.com/repos/JuliaLang/julia/milestones/26","html_url":"https://github.com/JuliaLang/julia/milestone/26","labels_url":"https://api.github.com/repos/JuliaLang/julia/milestones/26/labels","id":2761307,"node_id":"MDk6TWlsZXN0b25lMjc2MTMwNw==","number":26,"title":"1.1","description":"","creator":{"login":"ViralBShah","id":744411,"node_id":"MDQ6VXNlcjc0NDQxMQ==","avatar_url":"https://avatars2.githubusercontent.com/u/744411?v=4","gravatar_id":"","url":"https://api.github.com/users/ViralBShah","html_url":"https://github.com/ViralBShah","followers_url":"https://api.github.com/users/ViralBShah/followers","following_url":"https://api.github.com/users/ViralBShah/following{/other_user}","gists_url":"https://api.github.com/users/ViralBShah/gists{/gist_id}","starred_url":"https://api.github.com/users/ViralBShah/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ViralBShah/subscriptions","organizations_url":"https://api.github.com/users/ViralBShah/orgs","repos_url":"https://api.github.com/users/ViralBShah/repos","events_url":"https://api.github.com/users/ViralBShah/events{/privacy}","received_events_url":"https://api.github.com/users/ViralBShah/received_events","type":"User","site_admin":false},"open_issues":8,"closed_issues":4,"state":"open","created_at":"2017-09-12T21:17:46Z","updated_at":"2018-08-16T20:30:06Z","due_on":"2018-12-06T08:00:00Z","closed_at":null},"comments":75,"created_at":"2017-12-08T19:10:10Z","updated_at":"2018-08-24T20:44:46Z","closed_at":null,"author_association":"MEMBER","pull_request":{"url":"https://api.github.com/repos/JuliaLang/julia/pulls/24990","html_url":"https://github.com/JuliaLang/julia/pull/24990","diff_url":"https://github.com/JuliaLang/julia/pull/24990.diff","patch_url":"https://github.com/JuliaLang/julia/pull/24990.patch"},"body":"This PR addresses #554, #5571, and #22710 by \"currying\" underscores in function calls like `f(_,y)` into anonymous function expressions `x -> f(x,y)`.  (Note that `_.foo` works and turns into `x -> x.foo` since it is equivalent to a `getfield` call, and `_[i]` works and turns into `x -> x[i]`, since it is equivalent to a `getindex(_,i)` call.)\r\n\r\nThis will help us get rid of functions like `equalto` (#23812) or `occursin` (#24967), is useful for \"destructuring\" as discussed in #22710, and should generally be convenient in lots of cases to avoid having to explicitly do `x -> f(x,y)`.\r\n\r\nSome simplifying design decisions that I made:\r\n\r\n* The currying is \"tight\", i.e. it only converts the immediately surrounding function call into a lambda, [as suggested by](https://github.com/JuliaLang/julia/issues/22710#issuecomment-314259250) @JeffBezanson (and [as in Scala](https://www.scala-lang.org/files/archive/spec/2.11/06-expressions.html#placeholder-syntax-for-anonymous-functions)).   So, e.g. `f(g(_,y))` is equivalent to `f(x -> g(x,y))`.   (Note that something like `find(!(_ in c), y)` will work fine, because the `!` operator works on functions; you can also use `_ ∉ c`.)  Any other rule seems hard to make comprehensible and consistent.\r\n\r\n* ~~Only a single underscore is allowed.  `f(_,_)` throws an error: this case seems ambiguous to me (do you want `x -> f(x,x)` or `x,y -> f(x,y)`?), so it seemed better to punt on this for now.  We can always add a meaning for multiple underscores later.~~ Similar to Scala, multiple underscores are converted into multiple arguments in the order they appear.  e.g. `f(_,y,_)` is equivalent to `(x,z) -> f(x,y,z)`.  See [rationale below](https://github.com/JuliaLang/julia/pull/24990#issuecomment-350879561).\r\n\r\nThe implementation is pretty trivial.  If people are in favor, I will add\r\n- [x] Tests\r\n- [x] Documentation"},"comment":{"url":"https://api.github.com/repos/JuliaLang/julia/issues/comments/415877544","html_url":"https://github.com/JuliaLang/julia/pull/24990#issuecomment-415877544","issue_url":"https://api.github.com/repos/JuliaLang/julia/issues/24990","id":415877544,"node_id":"MDEyOklzc3VlQ29tbWVudDQxNTg3NzU0NA==","user":{"login":"bramtayl","id":9466324,"node_id":"MDQ6VXNlcjk0NjYzMjQ=","avatar_url":"https://avatars3.githubusercontent.com/u/9466324?v=4","gravatar_id":"","url":"https://api.github.com/users/bramtayl","html_url":"https://github.com/bramtayl","followers_url":"https://api.github.com/users/bramtayl/followers","following_url":"https://api.github.com/users/bramtayl/following{/other_user}","gists_url":"https://api.github.com/users/bramtayl/gists{/gist_id}","starred_url":"https://api.github.com/users/bramtayl/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/bramtayl/subscriptions","organizations_url":"https://api.github.com/users/bramtayl/orgs","repos_url":"https://api.github.com/users/bramtayl/repos","events_url":"https://api.github.com/users/bramtayl/events{/privacy}","received_events_url":"https://api.github.com/users/bramtayl/received_events","type":"User","site_admin":false},"created_at":"2018-08-24T20:44:46Z","updated_at":"2018-08-24T20:44:46Z","author_association":"CONTRIBUTOR","body":"Ok, so for some more thoughts, why not use curly brackets for specifying the boundaries? It seems a little less arbitrary than the \"tight\" rule? Downside is killing two syntaxes with one stone, but.\r\n\r\n ```\r\n1 |> {1 + _*_}\r\n```\r\n\r\nGoes to\r\n```\r\n1 |> (_ -> 1 + _*_)\r\n```\r\n\r\nMight be especially useful in places like JuliaDB, so to take an example from the docs, \r\n\r\n```\r\nLazy.@as x flights begin\r\n    select(x, (:UniqueCarrier, :DepDelay))\r\n    filter(i -> i.DepDelay > 60, x)\r\nend\r\n```\r\n\r\nCould go to\r\n```\r\nflights |>\r\n    { select(_, (:UniqueCarrier, :DepDelay)) } |>\r\n    { filter({ _.DepDelay > 60 }, _}) }\r\n```\r\n\r\nOne nice thing about this is the \"inside-out\"ness that comes with lowering but is tricky to do in macros.\r\n"}}
{"actor":{"display_login":"bramtayl"}}