Const facilitates change

Please have a look at the code below, it surprised me a lot. I am using 1.12.0-rc2. This file is P.jl and I developed a package called P; importing P gives this:

julia> import P
Info Given P was explicitly requested, output will be shown live 
MY_CONST 5
MY_CONST_ANNOTATED 5
GLOBAL_ANNOTATED 5
print_const_before(): Started.
MY_CONST 5
MY_CONST_ANNOTATED 5
print_const_before(): Done


Changing the values now!


MY_CONST aaa
MY_CONST_ANNOTATED aaa
print_const_before(): Started.
MY_CONST aaa
MY_CONST_ANNOTATED aaa
print_const_before(): Done
print_const_after(): Started.
MY_CONST aaa
MY_CONST_ANNOTATED aaa
print_const_after(): Done
Precompiling P finished.
  1 dependency successfully precompiled in 1 seconds
  1 dependency had output during precompilation:
┌ P
│  [Output was shown above]
└  

julia> 

To my surprise, Julia allows now to change value and type of a const parameter even when it is type annotated. This errors for non-const annotated variables. So the use of const makes type changes possible and I find that counterintuitive. Note that there is no warning and no error.

There is no trace of the freeze-in effect any more; after JIT compilation and use of a function, the const value would be embedded in the compiled function and changing it would not compile the function again, so the function would continue to use an old value of that const. This behavior is also no longer observed.

Question: is this intended behavior or a bug?

module P
    const MY_CONST = 5
    println("MY_CONST ", MY_CONST)
    
    const MY_CONST_ANNOTATED::Int64 = 5
    println("MY_CONST_ANNOTATED ", MY_CONST_ANNOTATED)
    
    global_var_annot::Int64 = 5
    println("GLOBAL_ANNOTATED ", global_var_annot)
    
    function print_const_before()::Nothing
        println("print_const_before(): Started.")
        println("MY_CONST ", MY_CONST)
        println("MY_CONST_ANNOTATED ", MY_CONST_ANNOTATED)

        println("print_const_before(): Done")
        return nothing
    end
    
    print_const_before()
    
    println("\n\nChanging the values now!\n\n")

    const MY_CONST = "aaa"
    println("MY_CONST ", MY_CONST)

    const MY_CONST_ANNOTATED::String = "aaa"
    println("MY_CONST_ANNOTATED ", MY_CONST_ANNOTATED)
    
    # global_var_annot::String = "aaa" # Comment this in and it fails.
 
    function print_const_after()::Nothing
        println("print_const_after(): Started.")
        println("MY_CONST ", MY_CONST)
        println("MY_CONST_ANNOTATED ", MY_CONST_ANNOTATED)

        println("print_const_after(): Done")
        return nothing
    end
    
    print_const_before()
    print_const_after()        
end # module P

From the (work in progress) 1.12 Release Notes:

2 Likes

See also this issue, for enabling warnings, and potentially changing the default behavior: