# Type inference with parametric composite types

**URL:** <https://discourse.julialang.org/t/type-inference-with-parametric-composite-types/21251>\
**Category:** New to Julia\
**Created:** [February 27, 2019, 7:15am UTC](https://discourse.julialang.org/t/type-inference-with-parametric-composite-types/21251 "2019-02-27T07:15:44Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![robsmith11](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/robsmith11/32/29641_2.png) [@robsmith11](https://discourse.julialang.org/u/robsmith11)\
**Post date:** [February 27, 2019, 7:15am UTC](https://discourse.julialang.org/t/type-inference-with-parametric-composite-types/21251/1 "2019-02-27T07:15:44Z")

</div>

In the example below, why can the type of `x` be inferred for `S1` but not for `S2`? Is this behavior documented anywhere or is it a bug?

```julia
julia> struct S1
           x::Vector{Int}
       end

julia> struct S2{N}
           x::Vector{Int}
           y::Vector{SVector{N,Int}}
       end

julia> S1([])
S1(Int64[])

julia> S2([], SVector{3,Int}[])
ERROR: MethodError: no method matching S2(::Array{Any,1}, ::Array{SArray{Tuple{3},Int64,1,3},1})
Closest candidates are:
  S2(::Array{Int64,1}, ::Array{SArray{Tuple{N},Int64,1,N},1}) where N at REPL[3]:2
Stacktrace:
 [1] top-level scope at REPL[5]:1

julia> S2(Int[], SVector{3,Int}[])
S2{3}(Int64[], SArray{Tuple{3},Int64,1,3}[])

```

---

<div class="post-metadata">

**Author:** ![JeffreySarnoff](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jeffreysarnoff/32/1980_2.png) [@JeffreySarnoff](https://discourse.julialang.org/u/JeffreySarnoff)\
**Post date:** [February 27, 2019, 7:49am UTC](https://discourse.julialang.org/t/type-inference-with-parametric-composite-types/21251/2 "2019-02-27T07:49:34Z")

</div>

`[]` is a vector of zero length. `SVector{3,Int}[]` asks for a StaticVector with 3 `Ints` to be obtained from a vector of 0 `Ints`.  
Use `@SVector([1,2,3])` if that’s what you want.

```julia
julia> s2 = S2([1,2,3],[@SVector([1,2,3,4])])
S2{4}([1, 2, 3], SArray{Tuple{4},Int64,1,4}[[1, 2, 3, 4]])

```

also, you do not need to wrap the SVector in a Vector

```julia
struct S2{N}
       x::Vector{Int}
       y::SVector{N,Int}
 end

julia> S2([1,2], @SVector([2,4])
S2{2}([1,2], [2,4])

```

---

<div class="post-metadata">

**Author:** ![c42f](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/c42f/32/52842_2.png) [@c42f](https://discourse.julialang.org/u/c42f)\
**Post date:** [February 27, 2019, 8:02am UTC](https://discourse.julialang.org/t/type-inference-with-parametric-composite-types/21251/3 "2019-02-27T08:02:15Z")

</div>

This is a bit subtle because the default outer constructor looks a bit different for the parametric vs non-parametric cases. I’m a bit hazy on this myself as the documentation at [Constructors · The Julia Language](https://docs.julialang.org/en/v1/manual/constructors/index.html#Parametric-Constructors-1) isn’t very explicit about the exact form for the default outer constructor.

In this particular case, I think the default outer constructor for `S2` is

```julia
S2(x::Array{Int64,1}, y::Array{SArray{Tuple{N},Int64,1,N},1}) where {N} = S2{N}(x,y)

```

Whereas for `S1`, the default outer constructor is

```julia
S1(x) = S1(convert(Vector{Int}, x))

```

So you can see why one case will match and the other will not. It does seem inconvenient though that the default outer constructor for `S2` doesn’t match and just use convert. The following issue suggests that it was to make it harder to accidentally introduce infinite recursion when defining extra constructors: [unintuitive type conversion in constructor with parametric type · Issue #10641 · JuliaLang/julia · GitHub](https://github.com/JuliaLang/julia/issues/10641).

---

<div class="post-metadata">

**Author:** ![robsmith11](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/robsmith11/32/29641_2.png) [@robsmith11](https://discourse.julialang.org/u/robsmith11)\
**Post date:** [February 27, 2019, 9:03am UTC](https://discourse.julialang.org/t/type-inference-with-parametric-composite-types/21251/4 "2019-02-27T09:03:30Z")

</div>

Just to clarify, I did want `y` to be a zero length `Vector` of `SVector{3,Int}`s.

I think Chris’s response about `S1` using `convert` clears my confusion.
