Hi,
In the following expression
using StaticArrays
using Random
Random.seed(42)
a = SVector{2, Float64}(1.0, 2)
b = a + rand(2)
I was initially (incorrectly) expecting that b’s type would be SVector{2, Float64}.
Instead, it’s SizedVector{2, Float64, Vector{Float64}}.
Debugging with @code_warntype, rand(2) is a Vector{Float} (though a compile time constant should allow it to pick SizedVector).
Debugging a bit more, I thought that the typing rules then use the intersection of types (typeintersect(typeof(a), typeof(rand(2)) to determine the type of the expression, but it seems I’m wrong there, as that intersection is Union{}.
I know that I can force (or be explicit) in my intent
b = a + rand(SVector{2, Float64}) # both parts of the expression are identical type, so no issues
Then, the plot thickended, because this
c = rand(2) + a # SVector, not SizedVector
actually does what I initially expected.
So this suggests the type is determined by R/L order of evaluation?
My questions are these:
-
What are the typing rules that determine typeof(b)? How, for future cases, could I check? I know code_warntype gives me the outcome and intermediate steps, but not the rules (so I can avoid the misaligned expectation).
-
rand(2) is implemented to give a Vector, so later invocations can push!() on it, that makes sense. However, then why would the expression
a + rand(2)
change to SizedVector? Initially I thought it used the intersection rules, but I seem to be incorrect about that. (note, from performance perspective, naturally it’s the right thing to do SizedVector here, though SVector would be ideal). It’s just that I can’t figure out how the rules work.
To explain:
a = SVector{2,Float64}(2, 3.0)
b = a + rand(2) # SizedVector
push!(b, 2) # Error, as it's static sized
c = rand(2) # Vector
push!(c, 2) # ok
d = rand(2) + a #SVector, not SizedVector
push!(d, 3.0) # Fails, as expected
I tried the above in a function, but it makes no difference, so it’s not a question of global scope affecting the outcome (unless I made a mistake somewhere).
In summary, where can I find how the type rules affect type inference (and is this dynamic, or compile time) for such expressions?
Any help understanding this will be greatly appreciated,