When one runs the following code, my expectation is that three methods would get defined.
# Default equal function:
preferred_equal_fn(x) = (===)
# Numbers use isequal
let x = isequal
preferred_equal_fn(::Type{T}) where {T <: Number} = x
end
# So do strings.
begin
local x = isequal
preferred_equal_fn(::Type{T}) where {T <: AbstractString} = x
end
However, the let block seems to prevent the definition:
methods(preferred_equal_fn)
# [Out] := #2 methods for generic function preferred_equal_fn:
# preferred_equal_fn(::Type{T}) where T<:AbstractString in Main at In[1]:12:
# preferred_equal_fn(x) in Main at In[1]:2
What’s going on here? Is this documented anywhere?
Thanks; that the global keyword fixes this seems intuitive. I seem to be a bit confused about the specific terminology, though. The documentation says that that begin blocks do not introduce a new scope, but it seems that they do respect local definitions, which I had taken to indicate a scoping layer.
x = 20
begin
local x = 10
println(x)
end
println(x)
# [Out] := 10
# [Out] := 20
Am I correct in thinking that soft and hard scopes actually have an effect on whether keywords like local are implicitly prepended to variable assignments inside them, while begin blocks form a kind of very-soft scope that doesn’t prepend anything?
julia> x = 20
20
julia> begin
x=20
println(x)
end
20
julia> x
20
julia> let x = 10
print(x)
end
10
julia> x
20
I hope this helps you to clear the view, basically, your begin + local is the same as a let block with local variables, and if you don’t have local, then you can directly change x inside the begin I think