Const fields in structs


#1

Version 0.6.0 (2017-06-19 13:05 UTC) x86_64-redhat-linux

Am I right, that const fields are not supported? It is possible to define a struct with const fields, but how to create an instance of it?

mutable struct F1
     a::Int
     const c = [1, 1]
end
# ok

f1 = F1(3) # fails
f1 = F1(3, [7, 8]) # fails also

#2

What are you trying to do exactly? Have a field which is identical among all instances of a type, or prevent modification of the field after the object has been constructed? If the latter, that’s not possible AFAIK (Julia considers that fields are private and that it’s your problem if you modify them when you are not supposed to). If the former, you can use a const global variable (local to the module in which it is defined).


#3

Ref https://github.com/JuliaLang/julia/issues/9448, https://github.com/JuliaLang/julia/pull/11430


#4

To not answer the OP question: This is a bit an odd corner case of Julia which people stumble across sometimes. This sheds a bit of light on it:

julia> mutable struct F1
            a::Int
            const c = [1, 1]
           F1(a) = (@show c; new(a))
       end                                                                                                                                            
                                                                                                                                                      
julia> F1(4)                                                                                                                                          
c = [1, 1]                                                                                                                                            
F1(4)
                                                                                                                                                
julia> mutable struct F2
            a::Vector
            const c = [1, 1]
           F2(a) = (@show c; new(a))
           F2() = new(c)
       end                                                                                                                                            
                                                                                                                                                      
julia> F2()                                                                                                                                           
F2([1, 1])                                                                                                                                            

julia> ans.a[1] = 7                                                                                                                                   
7                                                                                                                                                     

julia> F2([1])                                                                                                                                        
c = [7, 1]      # so c was mutated                                                                                                                                      
F2([1])

So, c is a variable inside the scope of the type definition. The only access to it, as far as I know is through inner constructors. There are some musings on what this could be useful here: https://github.com/JuliaLang/julia/issues/9443.

However, what most people think this should do (at least without the const) is to assign a default value to the field, see https://github.com/JuliaLang/julia/issues/10146. And this is also planned to be implemented. As part of this the following is now reserved:

julia> mutable struct F3
            a::Vector
            c = [1, 1]
       end
ERROR: syntax: "c=[1,1]" inside type definition is reserved

see https://github.com/JuliaLang/julia/commit/f7a4aa3e7fcfd4c419809e34dc5d6ee485846298. Apparently putting the const in front circumnavigates this reservation in the parser.


#5

There is also https://github.com/JuliaLang/julia/issues/18657, which states that the inner constructor should not be removed in this case.