I’m a beginner so please forgive me if I ask something obvious. Here is a sentence from the beginning of the Types · The Julia Language documentation:
Only values, not variables, have types – variables are simply names bound to values.
When I first saw this, I quickly put together the following code:
julia> let
println("One")
x::Integer = 6
println("Two")
x = "Test"
println("Three")
end
I have tried to figure out what will happen when I execute it. This was my thinking:
- The variable
x
is declared to hold values ofInteger
instances - In the
let
block, there is an assignment that tries to assign aString
value to that variable. - The documentation stated that variables don’t have types, only values do.
- So I would expect that Julia might not compile this block of code, because it contains an incompatible assignment. (Altough this would require that it knows the type of the value in advance. But in this case, this is attributable.)
- From the other side: if Julia can compile the above code, then it must not throw an exception when the assigment happens. The assignment just re-assigns the name after all, and the name
x
does not have a type. (Remember: only values can have types, not names.)
I was very suprised, because this is what happened:
One
Two
ERROR: MethodError: Cannot `convert` an object of type String to an object of type Integer
Closest candidates are:
convert(::Type{T}, ::T) where T<:Number at number.jl:6
convert(::Type{T}, ::Number) where T<:Number at number.jl:7
convert(::Type{T}, ::Ptr) where T<:Integer at pointer.jl:23
...
Stacktrace:
[1] top-level scope at none:5
Julia has compiled the code block before executing it, because “One” and “Two” were printed before the exception was thrown. I think it is clear that the code block was compiled at once, as a single compilation unit - the outermost let block must have been closed to form correct syntax, and also to define the scope of the variable x
. The scope of x
must have been determined before it was first assigned to. So the compilation succeded, the execution of the compiled code started and then a runtime error occured.
Julia called convert
when she tried to convert the value "Test"
to an Integer
. It is true, that the first value assigned to x
was an Integer
, but that is the type of the value, not the “type of the variable”. There should be no such thing as “the type of the variables”, because “variables don’t have types”. Then why did she fail to assign a string to x? Where did the knowledge came from about x
not being able to hold String
values? In theory, this could not come from the variable x
(wich is a variable, so it cannot have a type).
Either the documentation is not telling the whole truth, or maybe I’m not understanding something very fundamental about Julia.