Why can't I use any Unicode character in field name?

Hello!

I am just trying this:

struct Vec{Ti <: Number, Tj <: Number, Tk <: Number}
        ₁::Ti
        ₂::Tj
        ₃::Tk
    end

And it does not work for these unicode characters, but works for something like “\bbN”.

I am trying to see if I can make a syntax like:

a = Vec(1,1,1)

# Return first element
a₁

Is it possible?

Kind regards

See Allowed Variable names in the manual: identifiers cannot start with a number (including numeric subscripts).

Every programming language has some restrictions on the characters allowed in identifiers, and Julia is more permissive than most. (Python doesn’t allow numeric subscripts at all, e.g. x₃ is not a valid Python 3 identifier. Similarly for most other languages, thanks to a fairly restrictive recommendation from the Unicode consortium.)

See this issue for discussion on allowing identifiers to start with numeric subscripts/superscripts.

4 Likes

Thanks!

I hope it becomes permissible one day. I would love to write as close to math as possible, makes it much easier for me atleast.

I hope the suggestion with sub- and superscripts gets through sometime :slight_smile:

Kind regards

You’d still have to write v.₁ rather than v₁. v[1] is already widely considered to be the programming equivalent of subscripting with 1.

1 Like

I do not disagree at all, I had hoped there was a smart way to avoid the “.” as well, that I was not aware of yet :slight_smile:

I suppose I just like when it looks more as a₁ than a[1].

So this is one of the points I liked about Julia, thinking that I could write exactly how I would have wanted, but unfortunately not in this case. I guess some restrictions have to be in place.

Thanks for your comment!

a₁ is already a valid variable name, which isn’t going to change—it’s useful and changing it would be a breaking change. So that will never be possible as a syntax for a[1].

5 Likes

You could always manually assign a₁ to a.₁ (similarly for the other entries), or create a macro to automate it. E.g., @fancy_macro a = Vec(1, 1, 1) # Also defines a₁, etc.

Do you happen to know how?

Here’s a basic implementation that has no error checking (note that I changed the fields of the Vec struct to i, j, and k):

julia> macro define_fields(ex)
           name = ex.args[1]
           esc(quote
               $ex
               $(Symbol(name, "₁")) = $name.i
               $(Symbol(name, "₂")) = $name.j
               $(Symbol(name, "₃")) = $name.k
               $name
           end)
       end
@define_fields (macro with 1 method)

julia> @define_fields a = Vec(1, 2, 3)
Vec{Int64, Int64, Int64}(1, 2, 3)

julia> a₁, a₂, a₃
(1, 2, 3)

julia> @define_fields long_name = Vec(10, 20, 30)
Vec{Int64, Int64, Int64}(10, 20, 30)

julia> long_name₁, long_name₂, long_name₃
(10, 20, 30)

You could probably come up with a better name for the macro.

2 Likes