Trouble with Internal Constructor

I’m trying to do the following:

julia> mutable struct CustomSet{T}
elements:: Vector{T}
CustomSet(e) = new{CustomSet{T}}(sort(e))
end

I expect the inner constructor to return a new CustomSet with the Vector e sorted. But it doesn’t work.

julia> c = CustomSet([1,2,4,3])

CustomSet{Int64}([1, 2, 4, 3])

What am I doing wrong? Thanks.

You want new{T}(sort(e), not new{CustomSet{T}}(sort(e)). The parameters in {} for new are the same as the parameters of your type, not the type with its parameters. Otherwise you’re asking new to give you a CustomSet{CustomSet{T}}

Edit: for example, here’s a working implementation:

julia> mutable struct CustomSet{T}
         elements:: Vector{T}
         CustomSet(e::AbstractVector{T}) where {T} = new{T}(sort(e))
       end

julia> CustomSet([1,4,2,3])
CustomSet{Int64}([1, 2, 3, 4])

and here’s a slightly more general version:

julia> mutable struct CustomSet{T}
         elements:: Vector{T}
         CustomSet(e) = new{eltype(e)}(sort(e))
       end

julia> CustomSet([1,4,2,3])
CustomSet{Int64}([1, 2, 3, 4])
1 Like

Welcome back! Three things here:

  1. The struct definition you posted doesn’t behave like you posted. I see an error (UndefVarError: T not defined). I think you have leftover method definitions from earlier attempts.

  2. The parameterized new{...} takes just the type parameter for the struct. (Ah, yes, what Robin beat me to above)

  3. You need to tell Julia what that T is going to be — it doesn’t magically grab it for you in this case. So you want new{eltype(e)}.

So all together:

julia> mutable struct CustomSet{T}
           elements:: Vector{T}
           CustomSet(e) = new{eltype(e)}(sort(e))
       end

julia> CustomSet([1,2,4,3])
CustomSet{Int64}([1, 2, 3, 4])

Thanks - but that has the same result.

julia> mutable struct CustomSet{T}
elements:: Vector{T}
CustomSet(e) = new{T}(sort(e))
end

julia> c = CustomSet([1,2,4,3])
CustomSet{Int64}([1, 2, 4, 3])

This is one of those cases where you may need to restart Julia. You can also look into using Revise, but iterating on struct definitions isn’t its strong suit.

You can probably see what’s happening with methods(CustomSet). I’m guessing you have some outer constructors that are taking precedence.

Still doesn’t work (using Julia 1.62)

julia> mutable struct CustomSet{T}
elements:: Vector{T}
CustomSet(e) = new{eltype(e)}(sort(e))
end

julia> c = CustomSet([1,2,4,3])
CustomSet{Int64}([1, 2, 4, 3])

Restarting Julia, and retrying works. Thanks.