Is there any way to make custom binary infix operators right associative?


#1

If I define some new binary infix operator, it appears to always be left associative by default, i.e.

julia> ⨳(a,b) = (a,b)
julia> 1⨳2⨳3
((1,2),3)

Is there any to make it right associative instead? I had guessed defining something like this might work but it doesn’t,

⨳(args...) = foldr(⨳,args)

the call appears to always go to the two-argument function first with assumed left assosciativity.


#2

Associativity is a property of the operator. The only way to do this is to use a right associative binary operator. I believe arrows fit this description, as do assignments.


#3

Yep, you’re right about arrows,

julia> →(a,b) = (a,b)
julia> 1→2→3
(1,(2,3))

Any idea where there’s a list of what Julia assumes for each operator?

I guess it doesn’t make much sense to me that Julia picks the assosciativity based on the unicode character. Shouldn’t I, the programmer defining what these operators mean, get to pick?


#4

In order to define associativity the way you have, operators have to be parsed n-ary. Currently the only n-ary operators are + and * which are usually associative anyway. Unfortunately, even with n-ary parsing, mixing different operators with the same precedence will have the operator’s default associativity.

The reason operator associativity cannot be defined by the programmer in general (except via nary parsing, if applicable) is that the precedence of the operator must be known at parse time, whereas what the operator means is only knowable at runtime in general.


#5

I believe every operator listed as prec-arrow or prec-power in https://github.com/JuliaLang/julia/blob/master/src/julia-parser.scm is right-associative.


#6

Very helpful, explanation, thanks. So yea, it seems that for operators parsed as n-ary my attemped solution above works, e.g.

julia> import Base: +
julia> +(args::String...) = foldr(+,args)
julia> +(a::String, b::String) = "($a,$b)"
julia> "a"+"b"+"c"
"(a,(b,c))"

So I think really what I’d want is more operators to be parsed n-ary like + and * are (e.g. if my ⨳ above was included I’d be good). Which leads me to find https://github.com/JuliaLang/julia/issues/7368 where I’ll probably comment about this particular usefulness of parsing more things as n-ary, which doesn’t seem to have been mentioned there.


#7

This PR updates the documentation to list operator associativity as well as precedence:
https://github.com/JuliaLang/julia/pull/23754