from http://docs.julialang.org/en/latest/manual/constructors/

...This automatic provision of constructors is equivalent to the following 
explicit declaration:

type Point{T<:Real}
>
>   x::T
>
>   y::T
>
>
>>   Point(x,y) = new(x,y)
>
> end
>
>
>> Point{T<:Real}(x::T, y::T) = Point{T}(x,y)
>
>
Some features of parametric constructor definitions at work here deserve 
comment. ...

Would adding a highlighted/bold/italicized note before "Some features..." 
help? e.g.

*Important*
When an inner constructor is specified for a parameterized type, it is 
necessary to include the corresponding outer constructor to allow 
construction where the parameter value is not given explicitly.

type TimesTwo{T<:Real}
>     x::T
>     TimesTwo(x) = new(2*x)             # inner constructor

end

 

TimesTwo{T<:Real}(x) = TimesTwo{T}(x)      # outer constructor matching the 
> inner constructor


Without the matching outer constructor, you can do: a = TimesTwo{Int}(5), 
> but you cannot do a = TimesTwo(5).  With the matching outer constructor, 
> you can do both.


 

 

>  

 

  

   

On Saturday, June 4, 2016 at 12:00:22 AM UTC-4, Eric Forgy wrote:
>
> 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