# Understanding typing rules

**URL:** https://discourse.julialang.org/t/understanding-typing-rules/131087
**Category:** General Usage
**Tags:** type, staticarrays
**Created:** [July 27, 2025, 9:30am UTC](https://discourse.julialang.org/t/understanding-typing-rules/131087 "2025-07-27T09:30:54Z")
**Posts on this page:** 5
**Page:** 1

<div class="post-metadata">

### Author: ![benc](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/benc/32/46974_2.png) [@benc](https://discourse.julialang.org/u/benc)
#### Post date: [July 27, 2025, 9:30am UTC](https://discourse.julialang.org/t/understanding-typing-rules/131087/1 "2025-07-27T09:30:54Z")

</div>

Hi,

In the following expression

```julia
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

```julia
b = a + rand(SVector{2, Float64}) # both parts of the expression are identical type, so no issues

```

Then, the plot thickended, because this

```julia
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:

1. 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).

2. 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:

```julia
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,

---

<div class="post-metadata">

### Author: ![GunnarFarneback](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gunnarfarneback/32/1827_2.png) [@GunnarFarneback](https://discourse.julialang.org/u/GunnarFarneback)
#### Post date: [July 27, 2025, 9:54am UTC](https://discourse.julialang.org/t/understanding-typing-rules/131087/2 "2025-07-27T09:54:55Z")

</div>

I can’t reproduce this. (Specifically, I don’t get any `SizedVector` in your initial example.)

What versions of Julia and StaticArrays are you using? Do you do something more in your session? Do you have something interesting in your `startup.jl`?

> [@benc](#):
>
> rand(2) is a Vector{Float} (though a compile time constant should allow it to pick SizedVector)

What does this mean?

---

<div class="post-metadata">

### Author: ![benc](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/benc/32/46974_2.png) [@benc](https://discourse.julialang.org/u/benc)
#### Post date: [July 27, 2025, 10:32am UTC](https://discourse.julialang.org/t/understanding-typing-rules/131087/3 "2025-07-27T10:32:51Z")

</div>

You’re right, looks like my sessions was the cause, a clean session fixed the issue, apologies for the noise

---

<div class="post-metadata">

### Author: ![Benny](https://avatars.discourse-cdn.com/v4/letter/b/49beb7/32.png) [@Benny](https://discourse.julialang.org/u/Benny)
#### Post date: [July 27, 2025, 10:45am UTC](https://discourse.julialang.org/t/understanding-typing-rules/131087/4 "2025-07-27T10:45:46Z")

</div>

> [@GunnarFarneback](#):
>
> I can’t reproduce this. (Specifically, I don’t get any `SizedVector` in your initial example.)

A typo somewhere, you get `SizedVector` if you used broadcasted addition instead `a .+ rand(2)`. `StaticArray`s mostly defer to the other input for computing an output type for broadcasting:

```julia-auto
BroadcastStyle(::StaticArrayStyle{M}, ::DefaultArrayStyle{N}) where {M,N} =
    DefaultArrayStyle(Val(max(M, N)))

```

But eventually the special `StaticArrays` axes, if preserved perfectly, wraps the output array into the statically `SizedArray` wrapper:

```julia-auto
julia> similar(Array{Float64}, (SOneTo(2),))
2-element SizedVector{2, Float64, Vector{Float64}} with indices SOneTo(2):
 6.95242594095396e-310
 6.95242594094763e-310

```

A `SVector` result was possible with `Vector`, but a mutable output was chosen to be consistent with the mutable outputs of broadcasting with higher-dimensional `Array`s e.g. `a .+ reshape(1:100, 1, 100)` becomes 2x100, a size known only at runtime.

Direct `+` dispatches to a different method that can more reasonably choose to instantiate an `SArray` of the same size (indeed a compile time constant) because there is no broadcasting to change sizes; `a + reshape(1:100, 1, 100)` would not work. `map(+, a, [1, 2])` makes the same choice and is implemented by a `StaticArrays` method.

---

<div class="post-metadata">

### Author: ![benc](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/benc/32/46974_2.png) [@benc](https://discourse.julialang.org/u/benc)
#### Post date: [July 28, 2025, 8:11am UTC](https://discourse.julialang.org/t/understanding-typing-rules/131087/5 "2025-07-28T08:11:32Z")

</div>

Ah, thank you, I was thinking I had just imagined the whole thing even though the repl output was still in my terminal’s screen, I attributed it to a mistake on my part.  
Thanks for the explanation!
