julia> 5 + 5
10
julia> · = 5
5
julia> ·
5
julia> · + ·
ERROR: ParseError:
# Error @ REPL[31]:1:1
· + ·
╙ ── not a unary operator
Stacktrace:
[1] top-level scope
@ none:1
julia>
julia> '·'
'·': Unicode U+00B7 (category Po: Punctuation, other)
julia> / + /
ERROR: syntax: "/" is not a unary operator
Stacktrace:
[1] top-level scope
@ none:1
julia> '/'
'/': ASCII/Unicode U+002F (category Po: Punctuation, other)
You can’t use a single punctuation character as an identifier. Try a codepoint that is in a letter category.
julia> 'α'
'α': Unicode U+03B1 (category Ll: Letter, lowercase)
julia> α = 5
5
julia> α + α
10
https://docs.julialang.org/en/v1/manual/variables/#man-allowed-variable-names
What about Unicode code points from private areas? And why did the assignment work???
I don’t know about private areas, but you can assign to various thing like +
and /
, but they are otherwise parsed as binary operators.
julia> · = (x,y) -> x*y + x/y
#1 (generic function with 1 method)
julia> 3 · 4
12.75
Unfortunately Private Use Area glyphs aren’t available as identifiers:
julia-1.10> = 1
ERROR: ParseError:
# Error @ REPL[2]:1:1
= 1
╙ ── unknown unicode character '\ue800'
These functions might be useful:
julia-1.10> Base.isidentifier("d")
true
julia-1.10> Base.isoperator("⋅")
true
julia-1.10> Base.isunaryoperator(:!)
true
The discourse should allow marking multiple responses as solutions … your response will sure be worth it as it solves one aspect of the observed issue. The other response solves the main aspect as at the time of asking the question I was not aware that it is possible to assign to special kind of symbols which don’t act as names but as operators. May you please elaborate a bit more about Unicode code points which can be used as binary or unary or combined assigment ( +=
) ?
I’m not sure if it’s properly documented anywhere. It’s possible to look in the source, the file src/julia-parser.scm
, a lisp program to get an idea: julia/src/julia-parser.scm at master · JuliaLang/julia · GitHub
In fact, all julia’s operators are defined like this. You can see the definition of an operator with the @less
macro:
@less 2 + 3
displays the relevant portion of base/int.jl
where the operator +
between integers is defined as:
(+)(x::T, y::T) where {T<:BitInteger} = add_int(x, y)
where add_int
is an intrinsic (or is it builtin?) which isn’t really a function call, but just emits an llvm add instruction.
Going back to the first example, if you want to use an operator as a regular variable, use parentheses to disambiguate:
julia> 5 + 5
10
julia> · = 5
5
julia> ·
5
julia> (·) + (·)
10
If you need to check if something is a valid identifier, you can use Base.isidentifier
.
If you need to check if something is an operator, you can use Base.isoperator
, Base.isbinaryoperator
and Base.isunaryoperator
:
julia> Base.isidentifier("·")
false
julia> Base.isoperator("·")
true
julia> Base.isbinaryoperator(:·)
true