# Type inference: regression in 1.0?

**URL:** <https://discourse.julialang.org/t/type-inference-regression-in-1-0/15003>\
**Category:** New to Julia\
**Created:** [September 15, 2018, 9:55pm UTC](https://discourse.julialang.org/t/type-inference-regression-in-1-0/15003 "2018-09-15T21:55:09Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![Pavel\_Kalouguine](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pavel_kalouguine/32/7730_2.png) [@Pavel\_Kalouguine](https://discourse.julialang.org/u/Pavel_Kalouguine)\
**Post date:** [September 15, 2018, 9:55pm UTC](https://discourse.julialang.org/t/type-inference-regression-in-1-0/15003/1 "2018-09-15T21:55:09Z")

</div>

The following code works well in v0.6.4 but fails in v1.0:

```julia
module Scratch

using StaticArrays
abstract type AbstractX end

struct Foo{E<:AbstractX}
    v::Vector{E}
    function Foo{E}(v::Vector{E}) where {E}
        new(copy(v))
    end
end

struct ConcreteX{N,T} <: AbstractX
    w::SVector{N, T}
    function ConcreteX{N,T}(w::SVector{N, T}) where {N,T}
        new(w)
    end
end

function ConcreteX(w::SVector{N, T}) where {N,T}
     ConcreteX{N,T}(w)
end

const Bar{N,T}=Foo{ConcreteX{N,T}}

e1= ConcreteX(@SVector [1, 2])
e2= ConcreteX(@SVector [3, 4])

Bar([e1, e2])

end

```

The error message is:

```julia
ERROR: LoadError: MethodError: no method matching Main.Scratch.Foo{Main.Scratch.ConcreteX{N,T} where T} where N(::Array{Main.Scratch.ConcreteX{2,Int64},1})

```

(at the line 29).  
**Update**  
Explicit type specification  
Bar{2,Int}([e1, e2])  
is a possible workaround. But I still do no see how one can help Julia to infer the type parameters of Bar.

---

<div class="post-metadata">

**Author:** ![Keno](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/keno/32/285_2.png) [@Keno](https://discourse.julialang.org/u/Keno)\
**Post date:** [September 15, 2018, 11:16pm UTC](https://discourse.julialang.org/t/type-inference-regression-in-1-0/15003/2 "2018-09-15T23:16:22Z")

</div>

Type inference has nothing to do with this, it’s more of a subtyping question. You probably want something like:

```julia
module Scratch

       using StaticArrays
       abstract type AbstractX end

       struct Foo{E<:AbstractX}
           v::Vector{E}
           function (::Type{<:Foo})(v::Vector{E}) where {E}
               new{E}(copy(v))
           end
       end

       struct ConcreteX{N,T} <: AbstractX
           w::SVector{N, T}
           function ConcreteX{N, T}(w::SVector{N, T}) where {N,T}
               new{N,T}(w)
           end
       end

       function ConcreteX(w::SVector{N, T}) where {N,T}
            ConcreteX{N,T}(w)
       end

       const Bar{N,T}=Foo{ConcreteX{N,T}}

       e1= ConcreteX(@SVector [1, 2])
       e2= ConcreteX(@SVector [3, 4])

       x = Bar([e1, e2])

       end

```

---

<div class="post-metadata">

**Author:** ![Pavel\_Kalouguine](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pavel_kalouguine/32/7730_2.png) [@Pavel\_Kalouguine](https://discourse.julialang.org/u/Pavel_Kalouguine)\
**Post date:** [September 15, 2018, 11:34pm UTC](https://discourse.julialang.org/t/type-inference-regression-in-1-0/15003/3 "2018-09-15T23:34:13Z")

</div>

I am a bit confused with this construction:

> [@Keno](#):
>
> function (::Type{\<:Foo})(v::Vector{E}) where {E} new{E}(copy(v)) end

I thought that new() is usable in inner constructors only, and the above syntax is that of a callable type.

---

<div class="post-metadata">

**Author:** ![yuyichao](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yuyichao/32/20_2.png) [@yuyichao](https://discourse.julialang.org/u/yuyichao)\
**Post date:** [September 15, 2018, 11:41pm UTC](https://discourse.julialang.org/t/type-inference-regression-in-1-0/15003/4 "2018-09-15T23:41:21Z")

</div>

> [@Pavel\_Kalouguine](#):
>
> inner constructors only

This is a case where, IMHO, giving things names only makes it more confusing…

In any case, `new` is usuable for functions defined within the type, period.

---

<div class="post-metadata">

**Author:** ![Pavel\_Kalouguine](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pavel_kalouguine/32/7730_2.png) [@Pavel\_Kalouguine](https://discourse.julialang.org/u/Pavel_Kalouguine)\
**Post date:** [September 15, 2018, 11:58pm UTC](https://discourse.julialang.org/t/type-inference-regression-in-1-0/15003/5 "2018-09-15T23:58:33Z")

</div>

> [@yuyichao](#):
>
> In any case, `new` is usuable for functions defined within the type, period.

I like this syntax, but is it documented somewhere?

---

<div class="post-metadata">

**Author:** ![jeff.bezanson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jeff.bezanson/32/48_2.png) [@jeff.bezanson](https://discourse.julialang.org/u/jeff.bezanson)\
**Post date:** [September 16, 2018, 5:15pm UTC](https://discourse.julialang.org/t/type-inference-regression-in-1-0/15003/6 "2018-09-16T17:15:58Z")

</div>

Yes, `new{ }` is described in the manual chapter on constructors.

The key to understanding this is that there’s no real distinction between a constructor and a “callable type”. Every method definition can be written two ways: either by specifying the (singleton) instance of the called thing, or by specifying its type. So `function f(x)` can also be written as `function (::typeof(f))(x)`. (Detail: the second form requires `f` to be assigned already.) For types, it looks like `function Int(x)` or `function (::Type{Int})(x)` but the idea is the same.

It’s quite possible the manual chapter should be rewritten not to refer to “inner” and “outer” constructors. The only distinctions that matter are (1) what type is the method defined for, and (2) is it written inside the `struct` block, giving it access to `new`. These two are completely orthogonal.

---

<div class="post-metadata">

**Author:** ![Pavel\_Kalouguine](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pavel_kalouguine/32/7730_2.png) [@Pavel\_Kalouguine](https://discourse.julialang.org/u/Pavel_Kalouguine)\
**Post date:** [September 19, 2018, 6:07pm UTC](https://discourse.julialang.org/t/type-inference-regression-in-1-0/15003/7 "2018-09-19T18:07:42Z")

</div>

Thank you, this clarifies the situation. As for the manual, I guess that the issue is larger than the story of “inner” and “outer” constructors. The very notion of constructor seems to be quite different in Julia from what people are used to in other languages. As far as I understand, in Julia it is not a hard-coded feature of the language, but rather an idiom (a particular case of a “callable thing”).
