a "canonical" way of defining an internal constructor of a parametric type:
immutable MyType{T<:"specific abstract type"} x::T MyType(x) = new(x + x) end
instead of declaring a common function MyType(x) , which can take arbitrary values, julia automatically determines the set of specific MyType(x::T) , where T<:"specific abstract type" . therefore your last two examples are equivalent to this.
as we know, the functionality of new is to create new objects, it is not necessary to make it parametric, because we have already applied restrictions before we call this function.
FYI, the default constructor is different from the one described above:
immutable MyType{T<:"specific abstract type"} x::T end
here, julia does one more thing: define an external constructor:
MyType{T<:"specific abstract type"}(x::T) = MyType{T}(x)
julia> methods(MyType) 3-element Array{Any,1}: call{T<:Integer}(::Type{MyType{T<:Integer}}, x::T<:Integer) at none:2 call{T}(::Type{T}, arg) at essentials.jl:56 call{T}(::Type{T}, args...) at essentials.jl:57
a
julia> immutable MyType{T<:Integer} x::T MyType(x) = new(x) end julia> methods(MyType) 2-element Array{Any,1}: call{T}(::Type{T}, arg) at essentials.jl:56 call{T}(::Type{T}, args...) at essentials.jl:57
this means that you may need to define this external constructor manually if you want to create your own internal constructor.