Mutation of constants

As documented, why do we even allow these in the first place? Why and how would they be useful?

  1. Constant mutated to a different memory location without warning.
julia> const s1 = "1"
"1"

julia> s2 = "1"
"1"

julia> pointer.([s1, s2], 1)
2-element Array{Ptr{UInt8},1}:
 Ptr{UInt8} @0x00000000132c9638
 Ptr{UInt8} @0x0000000013dd3d18

julia> s1 = s2
"1"

julia> pointer.([s1, s2], 1)
2-element Array{Ptr{UInt8},1}:
 Ptr{UInt8} @0x0000000013dd3d18
 Ptr{UInt8} @0x0000000013dd3d18
  1. Constant mutated to a different memory location with warning:
julia> const a = [1]
1-element Array{Int64,1}:
 1

julia> a = [1]
WARNING: redefining constant a
1-element Array{Int64,1}:
 1

Note the following from the docs you linked:

Note that although sometimes possible, changing the value of a const variable is strongly discouraged, and is intended only for convenience during interactive use. Changing constants can cause various problems or unexpected behaviors. For instance, if a method references a constant and is already compiled before the constant is changed then it might keep using the old value

so it is not something that is encouraged, but nevertheless not ruled out because it can be useful during interactive development.

Also, when you reassign the first s1 in your example above, it is fine because

julia> "1" ≡ "1"
true

(strings are not mutable and you are not supposed to care about pointers).

1 Like

Specifically, when you reload top-level code from a file, constants are redefined, often with the same value. Even when the value changes, it will usually also redefine all the functions that refer to those constants, so things will continue to work anyway. Disallowing this would make it essentially impossible to just reload top-level code that defines any constants, even though that’s really handy and currently perfectly possible with some warnings.

3 Likes

Sounds reasonable but would it be nicer if a constant is guaranteed to be a constant for non-interactive usage? Maybe we could allow mutation in Main only?

I typically define constants in modules. As long as I can reload a module (via Revise) to get the updates then I’m fine.

This is probably extremely minor in the grand scheme of things :nerd_face:

Do you write non interactive programs that modify source code of libraries and then reload them?

(On these occasions, I realize that I am living a pretty sheltered life :wink:)

I don’t really get the problem—if your code doesn’t produce any warnings, it’s fine. It seems like one should generally not be in the habit of writing production code that emits warnings. I suppose we could have a flag that turns any kind of language warning into an error.

4 Likes

I guess changing a constant to something of the same value would be quite fruitless anyways. So is it a “problem”? Maybe not.

Conceptually, it just feels wrong to be able to change constants. That’s all.

1 Like