I would like to know what is the different between the two types of constructers I used here (both are commented).
I don’t know which one is correct, because I sometimes randomly gets error while using one, but no error with other . I know this random error is very vauge, but I think understanding the difference will help me to understand the errors.
The two forms you provide are different in several respects:
the first uses {T} ... where {T}, which is the new recommended syntax, while the second one uses {T}( ... {T}), which has been deprecated,
the second one dispatches on the type, which is OK but not necessary here,
the second one calls new with a type parameter, which is not necessary here (implied by context).
If you are getting a error, it is best to provide a minimal working example (MWE). These kind of errors are not “random”, but usually easily reproducible.
Also see the latest release notes on constructors, and the two issues referenced there (if you want to learn about the history of this syntax).
Not yet. Also the form that is planing to be deprecated is ...{T}(...) in favor of ...(...) where {T}.
Not sure what do you mean here. The first one is also dispatching on the type.
No it’s not implied by context.
The main difference is that the first one is the recommanded syntax for inner constructor, it’s the same as the one on older version but without implicitly assuming a type parameter. The second one is almost the only way to get cross-version support though. Both should work when writen correctly but that is not necessarily trivial to do so if you get an error, posting the actual code would be useful.
No it’s not. The old inner constructor syntax is deprecated, using ...{T}(...) to specify type parameter, which is the only thing constructor 2 is doing, is not. Bottom line is that constructor 2, along with all features of the language and syntax it uses, it not deprecated.
Thanks both of for your replies. But I’m more puzzled by the observations below.
I define a new type as
type MyType1{T}
x::Vector{T}
c::Int64
MyType1{T}() where {T} = new( Vector{T}(), 1 ); # Constructor-1
(::Type{MyType1{T}}){T}() = new{T}( Vector{T}(), 2 ); # Constructor-2
end
# Now I can do
julia> t1 = MyType1{Int64}()
MyType1{Int64}(Int64[], 2) # The second constructor is called( c=2 here )
julia> which( MyType1{Int64}, () )
(::Type{MyType1{T}})() where T in Main at REPL[1]:6
Now, say if I define the constructors in opposite order, like below
type MyType2{T}
x::Vector{T}
c::Int64
(::Type{MyType2{T}}){T}() = new{T}( Vector{T}(), 2 ); # Constructor-2
MyType2{T}() where {T} = new( Vector{T}(), 1 ); # Constructor-1
end
# Now I can do
julia> t2 = MyType2{Int64}()
MyType2{Int64}(Int64[], 1) # This is constructor-1 ( c=1 )
So far it seems like the latest defined constructor is taking the action.
But if I do
julia> which( MyType2{Int64}, () )
(::Type{MyType2{T}})() where T in Main at REPL[4]:6
struct MyType1
x::Int64
MyType1() = new( 1 ); # Constructor-1
(::Type{MyType1})() = new( 2 ); # Constructor-2
end
julia> methods( MyType1 )
# 2 methods for generic function "(::Type)":
MyType1() in Main at REPL[1]:4
(::Type{T})(arg) where T in Base at sysimg.jl:24
# Till here okay
julia> which( MyType1, () )
MyType1() in Main at REPL[3]:1
# So 'which()' tells that it's going to call Constructor-1
julia> MyType1()
MyType1(2)
# but called constructor-2, which is the latest defined one: ( x=2 here )
struct MyType2
x::Int64
(::Type{MyType2})() = new( 2 ); # Constructor-2
MyType2() = new( 1 ); # Constructor-1
end
julia> methods( MyType2 )
# 2 methods for generic function "(::Type)":
MyType2() in Main at REPL[7]:4
(::Type{T})(arg) where T in Base at sysimg.jl:24
julia> which( MyType2, () )
MyType2() in Main at REPL[7]:4
# Here again 'which()' reports constructor-1
julia> MyType2()
MyType2(1)
# and calls constructor-1 ( x=1 here ), which is the latest defintion
It’s telling you that it’s calling constructor 2 they are exactly the same and the printing is normalized. I’m not sure why the line number shows up incorrectly for you but this shows the correct linenumber for me.
julia> struct MyType1
x::Int64
MyType1() = new( 1 ); # Constructor-1
(::Type{MyType1})() = new( 2 ); # Constructor-2
end
julia> @which MyType1()
MyType1() in Main at REPL[2]:4