World age is expected to produce a delay between a method or Task’s compiled code and their changes to the global state, but it wasn’t clear to me what happens in top-level begin or let blocks. Weirdly, there’s this discrepancy between eval and @eval, and I still don’t know whether these blocks are supposed to commit to a specific world age or not. I haven’t exhaustively wrote versions for all blocks in Julia, but it also applies to for and while.
julia> const pi = 3 # v1.12.2
3
julia> begin
println(pi)
const pi = 3.1 # possible here without manual eval
println(pi) # updated
end;
3
3.1
julia> begin
println(pi)
@eval const pi = 3.14
println(pi) # updated
end;
3.1
3.14
julia> begin
println(pi)
eval(:(const pi = 3.141))
println(pi) # obsolete
end;
3.14
3.14
julia> let
println(pi)
@eval const pi = 3.1415
println(pi) # updated
end;
3.141
3.1415
julia> let
println(pi)
eval(:(const pi = 3.14159))
println(pi) # obsolete
end;
3.1415
3.1415
The first tls_world_age example in the Manual page also changes to show the local world age incrementing if Core.eval is changed to @eval.
julia> function f end
f (generic function with 0 methods)
julia> begin
@show (Int(Base.get_world_counter()), Int(Base.tls_world_age()))
@eval @__MODULE__() f() = 1
@show (Int(Base.get_world_counter()), Int(Base.tls_world_age()))
f()
end
(Int(Base.get_world_counter()), Int(Base.tls_world_age())) = (38693, 38693)
(Int(Base.get_world_counter()), Int(Base.tls_world_age())) = (38694, 38694)
1