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
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.
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.
Hello @Mason,
Thanks for these concerns.
I proposed the operator at Polar coordinate representation · Issue #35576 · JuliaLang/julia · GitHub.