Why some operator symbols aren't allowed?

Hello,

Why some symbols aren’t allowed to create new operators?

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

julia> ∠(a, b) = a + b
julia> 1 ∠ 2
ERROR: syntax: extra token "∠" after end of expression
Stacktrace:
 [1] top-level scope at REPL[3]:0

The Julia parser only recognizes this predefined set of symbols as infix operators.

4 Likes

To exclude some reasons:

julia> →
ERROR: UndefVarError: → not defined

julia> ∠
ERROR: UndefVarError: ∠ not defined

They aren’t in use yet.

julia> '→'
'→': Unicode U+2192 (category Sm: Symbol, math)

julia> '∠'
'∠': Unicode U+2220 (category Sm: Symbol, math)

And, both are Unicode.

It’s a difficult balance because making an operator infix is not free. Allowing a symbol to be used infix can often make it more awkward to use regularly.

For example, a question appeared on Slack yesterday about why you can’t declare a struct whose name is *:

julia> struct * <: Real
           n::Int
       end 
ERROR: syntax: "*" is not a unary operator
Stacktrace:
 [1] top-level scope at none:0
 [2] eval(::Module, ::Any) at ./boot.jl:331
 [3] eval_user_input(::Any, ::REPL.REPLBackend) at /home/mason/julia/usr/share/julia/stdlib/v1.4/REPL/src/REPL.jl:86
 [4] run_backend(::REPL.REPLBackend) at /home/mason/.julia/packages/Revise/0meWR/src/Revise.jl:1075
 [5] top-level scope at none:0

The answer is that this is being parsed funny due to * being infix. Instead, you need to wrap * in parens to make it parse correctly:

julia> struct (*) <: Real
           n::Int
       end

julia> *(1)
*(1)

Because of stuff like this, we keep a small list of allowed infix operators and only add new ones if someone can offer a compelling reason why they or anyone else would want that particular symbol.

4 Likes

Hello @Mason,

Thanks for these concerns.

I proposed the operator at Polar coordinate representation · Issue #35576 · JuliaLang/julia · GitHub.

2 Likes