I've been bitten by this many times and see so many others being bitten. I 
know the docs explain this as well as I could, but it would be great if 
someone could come up with some educational magic to improve the docs a bit 
more.

On Saturday, June 4, 2016 at 10:17:16 AM UTC+8, David P. Sanders wrote:
>
>
>
> El viernes, 3 de junio de 2016, 22:06:20 (UTC-4), xdavidliu escribió:
>>
>> with
>>
>>
>> type foo
>>     x::Int
>>     foo(x) = x > 0 ? new(x) : new(-x)
>> end
>>
>>
>> type bar{T<:Integer}
>>     x::T
>> end
>>
>>
>> type baz{T<:Integer}
>>     x::T
>>     baz(x) = x > 0 ? new(x) : new(-x)
>> end
>>
>>
>>
>> "foo(-5).x" gives 5, "bar(-5).x" gives -5, but "baz(-5).x" gives a 
>> "MethodError: 'convert' has no method matching..." error. 
>>
>> It seems the relevant section in the manual is this 
>> <http://docs.julialang.org/en/release-0.4/manual/constructors/#parametric-constructors>,
>>  
>> but I only have a single field (as opposed to the examples in the link in 
>> which there are almost always two or more fields), so there should be no 
>> type disagreement or ambiguity here. Is this intended behavior?
>>
>
> This is rather subtle.
> The inner constructor defines *only* the parametrised constructor:
>
> julia> type baz{T<:Integer}
>                   x::T
>                   baz(x) = x > zero(x) ? new(x) : new(-x)
>               end
>
> julia> methods(baz)
> 2-element Array{Any,1}:
>  call{T}(::Type{T}, arg) at essentials.jl:56
>  call{T}(::Type{T}, args...) at essentials.jl:57
>
> julia> baz{Int}(-5)
> baz{Int64}(5)
>
> If you want to use a non-parametrized constructor like baz(-5), you need 
> to explicitly define it:
>
> julia> baz{T}(x::T) = baz{T}(x)
>
> Note that on the left, this means "for each T, define a function baz(x) 
> for x of that type"; on the right it tells you to call the parametric 
> constructor with *that particular* type T:
>
> julia> baz(-5)
> baz{Int64}(5)
>  
>

Reply via email to