For what it’s worth, one of the more confusing things is that the name resolution is within the scope and a syntactic, not semantic thing. By this, I mean:
julia> x=1; julia> function f() @show x false && (x=1) nothing end julia> function g() @show x #false && (x=1) nothing end julia> f() ERROR: UndefVarError: x not defined julia> g() x = 1
In principle, I would prefer a splitting into
UndefGlobalVarError (no local binding of that name exists, and at runtime there is no global of that name) and
UnInitializedVarError (a binding for this symbol exists in the scope, but has not yet been assigned at time of use – all control flows leading to a use before assignment must give us this error, but this may need to be tracked at runtime due to
@goto, if the halting problem for the specific user code is too hard for the compiler).