Parametric inner constructor with `where {T}` of non-parametric type

Consider the following type definition attempt, which tries to define a type that stores arrays of x- and y-locations of points:

julia> struct PointVector{T<:Real}
           x::Vector{T}
           y::Vector{T}
           PointVector{T<:Real}(x, y) = new(x, y)
       end

WARNING: deprecated syntax "inner constructor PointVector(...) around REPL[0]:4".
Use "PointVector{T}(...) where T" instead.
ERROR: syntax: function static parameter names not unique

We realize that in defining the inner constructor, the old syntax (without where) does not work.

This is fine, because I like the new syntax with where and it works:

julia> struct PointVector{T<:Real}
           x::Vector{T}
           y::Vector{T}
           PointVector{T}(x, y) where {T<:Real} = new(x, y)
       end

julia> PointVector{Int64}([1,0], [0,1])
PointVector{Int64}([1, 0], [0, 1])

Now, consider another example that attempts to define PointVectorFloat64, a version of PointVector that stores x and y only in Vector{Float64} type:

julia> struct PointVectorFloat64
           x::Vector{Float64}
           y::Vector{Float64}
           PointVectorFloat64(x::Vector{T}, y::Vector{T}) where {T<:Real} = new(float.(x), float.(y))
       end
ERROR: TypeError: Type{...} expression: expected UnionAll, got Type{PointVectorFloat64}

The type definition intends to define an inner constructor that is callable only for vectors x and y with real entries. However, as can be seen in the above example, the new syntax with where does not work in defining the inner constructor.

On the other hand, the old syntax without where still works:

julia> struct PointVectorFloat64
           x::Vector{Float64}
           y::Vector{Float64}
           PointVectorFloat64{T<:Real}(x::Vector{T}, y::Vector{T}) = new(float.(x), float.(y))
       end

julia> PointVectorFloat64([1.0, 0.0], [0.0, 1.0])
PointVectorFloat64([1.0, 0.0], [0.0, 1.0])

To summarize, it seems that a parametric inner constructor for a non-parametric type cannot be defined using the new syntax with where. Is there a way to define such an inner constructor using the new syntax?

This should not work on 0.5 either. You are defining an inner parameter with an unused type parameter.

julia> immutable P{T}
           P{T}() = new()
       end
WARNING: static parameter T does not occur in signature for Type at REPL[1]:2.
The method will not be callable.

Seems like a bug.

1 Like

Thanks for the clarification! Will issue a bug report.