Issue with using Unicode in symbol names

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> 
1 Like
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

3 Likes

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
5 Likes

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
1 Like

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.

1 Like

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
2 Likes