{"action":"created","issue":{"url":"https://api.github.com/repos/JuliaLang/julia/issues/16985","repository_url":"https://api.github.com/repos/JuliaLang/julia","labels_url":"https://api.github.com/repos/JuliaLang/julia/issues/16985/labels{/name}","comments_url":"https://api.github.com/repos/JuliaLang/julia/issues/16985/comments","events_url":"https://api.github.com/repos/JuliaLang/julia/issues/16985/events","html_url":"https://github.com/JuliaLang/julia/issues/16985","id":160890266,"number":16985,"title":"Custom infix operators","user":{"login":"jamesonquinn","id":372468,"avatar_url":"https://avatars.githubusercontent.com/u/372468?v=3","gravatar_id":"","url":"https://api.github.com/users/jamesonquinn","html_url":"https://github.com/jamesonquinn","followers_url":"https://api.github.com/users/jamesonquinn/followers","following_url":"https://api.github.com/users/jamesonquinn/following{/other_user}","gists_url":"https://api.github.com/users/jamesonquinn/gists{/gist_id}","starred_url":"https://api.github.com/users/jamesonquinn/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jamesonquinn/subscriptions","organizations_url":"https://api.github.com/users/jamesonquinn/orgs","repos_url":"https://api.github.com/users/jamesonquinn/repos","events_url":"https://api.github.com/users/jamesonquinn/events{/privacy}","received_events_url":"https://api.github.com/users/jamesonquinn/received_events","type":"User","site_admin":false},"labels":[{"url":"https://api.github.com/repos/JuliaLang/julia/labels/speculative","name":"speculative","color":"999999"}],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":56,"created_at":"2016-06-17T13:39:22Z","updated_at":"2016-06-26T11:30:00Z","closed_at":null,"body":"There is a discussion at https://groups.google.com/forum/#!topic/julia-dev/FmvQ3Fj0hHs about creating a syntax for custom infix operators. \r\n\r\n...\r\n\r\nEdited to add note: @johnmyleswhite has pointed out that the comment thread below is an invitation to bikeshedding. Please refrain from new comments unless you have something truly new to add. There are several proposals below, marked by \"hooray\" emoticons (exploding cone). You can use those icons to skip discussion and just read the proposals, or to find the different proposals so you can vote \"thumbs up\" or \"thumbs down\". \r\n\r\nUp/downvotes on this bug as a whole are about whether you think that Julia should have any custom infix idiom. Up/downvotes for the specific idea below should go on @Glen-O's first comment. (The bug had 3 downvotes and 1 upvote before that was clarified.)\r\n\r\n...\r\n\r\nInitial proposal (historical interest only):\r\n\r\nThe proposal that seems to have won out is:\r\n```\r\n    a |>op<| b #evaluates (in the short term) and parses (in the long term) to `op(a,b)`\r\n```\r\n\r\nIn order to have this work, there are only minor changes necessary:\r\n\r\n- Put the precedence of `<|` above that of `|>`, instead of being the same.\r\n- Make `<|` group left-to-right.\r\n- Make the function `<|(a,b...)=(i...)->a(i...,b...)`. (as pointed out in the discussion thread, this would have standalone uses, as well as its use in the above idiom)\r\n\r\nOptional:\r\n- create new functions `>|(a...,b)=(i...)->b(a...,i...)` and `|<(a,b...)=a(b...)` with appropriate precedences and grouping.\r\n    - Pipe first means evaluation, and pipe last maintains it as a function, while the > and < indicate which one is the function.\r\n- create new functions `>>|(a...,b)=(i...)->b(i...,a...)` and `<<|(a,b...)=(i...)->a(b...,i...)` with appropriate precedence and grouping.\r\n- create synonyms `»`, `⁍`, and(/or) `pipe` for `|>`; `«`, `⁌`, and(/or) `rcurry` for `<|`; and(/or) `lcurry` for `<<|`; with the single-character synonyms working as infix operators.\r\n- create an `@infix` macro in base which does the first parser fix below.\r\n\r\nLong term:\r\n- teach the parser to change `a |>op<| b` to `op(a,b)`, so there's no extra overhead involved when running the code, and so that operators can actually be defined in infix position. (This is similar to how the parser currently treats the binary `a:b` and the ternary `a:b:c` differently. For maximum customizability, it should do this for matched synonyms, but not for unmatched synonyms, so that e.g. `a |> b « c` would be still be treated as two binary operators.)\r\n- teach the parser to understand commas and/or spaces so that the ellipses in the above definitions work as expected without extra parentheses.\r\n\r\n(relates to https://github.com/JuliaLang/julia/issues/6946)\r\n"},"comment":{"url":"https://api.github.com/repos/JuliaLang/julia/issues/comments/228596682","html_url":"https://github.com/JuliaLang/julia/issues/16985#issuecomment-228596682","issue_url":"https://api.github.com/repos/JuliaLang/julia/issues/16985","id":228596682,"user":{"login":"jamesonquinn","id":372468,"avatar_url":"https://avatars.githubusercontent.com/u/372468?v=3","gravatar_id":"","url":"https://api.github.com/users/jamesonquinn","html_url":"https://github.com/jamesonquinn","followers_url":"https://api.github.com/users/jamesonquinn/followers","following_url":"https://api.github.com/users/jamesonquinn/following{/other_user}","gists_url":"https://api.github.com/users/jamesonquinn/gists{/gist_id}","starred_url":"https://api.github.com/users/jamesonquinn/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jamesonquinn/subscriptions","organizations_url":"https://api.github.com/users/jamesonquinn/orgs","repos_url":"https://api.github.com/users/jamesonquinn/repos","events_url":"https://api.github.com/users/jamesonquinn/events{/privacy}","received_events_url":"https://api.github.com/users/jamesonquinn/received_events","type":"User","site_admin":false},"created_at":"2016-06-26T11:30:00Z","updated_at":"2016-06-26T11:30:00Z","body":"This is my last post in this thread, unless there's positive reaction to my hacked juliaparser.\r\n\r\nI'm arguing in favor of infix macros here. That doesn't mean I'm not aware of the arguments against. Here's how I'd summarize the best argument against:\r\n\r\n> Language features start at -100. What do infix macros offer that could possibly overcome that? By their very nature, there is nothing you could accomplish with infix macros that couldn't be accomplished with prefix macros.\r\n\r\nMy response is: Julia is first of all a language for STEM programmers. Mathematicians, engineers, statisticians, physicists, biologists, machine learning people, chemists, econometricians... And one thing that I think most of those people realize is the usefulness of a good notation. To take an example I'm familiar with in statistics: adding independent random variables is equivalent to convolving PDFs, or even to convolving derivatives of CDFs, but often expressing something using the former can be an order of magnitude more concise and understandable than the latter.\r\n\r\nInfix versus prefix versus postfix is, to some degree, a matter of taste. But there are also objective reasons to prefer infix in many cases. Whereas prefix and postfix lead to piles of operators that make Forth programmers sound like German politicians, and Lisp programmers sound like a Chomskian caricature, infix puts the operators in what's often the cognitively most natural place, as near to their operands as possible. There's a reason nobody writes math papers in Forth.\r\n\r\nYes, infix macros could be used to write obfuscated code. But existing prefix macros are just as prone to abuse. If not abused, infix macros can lead to **much clearer** code. `(a+b @choose b)` beats `binomial(a+b,b)`; `score ~ age + treatment` beats `linearDependency(:score, :(age + treatment))`; and  `selectDomElement(\"#logo\") @| css(\"color\",\"red\") @| fadeIn(\"slow\") @| addClass(\"dummy\")` beats the holy hell out of `addClass(fadeIn(css(selectDomElement(\"#logo\"),\"color\",\"red\"),\"slow\"),\"dummy\")`. I realize that these are just toy examples but I think the principle is valid."}}
{"actor":{"display_login":"jamesonquinn"}}