The short version is that this is how default constructors are defined, and
the details don't matter that much.
Here are some clarifications:
12 # this is a value of type Int
Int # this is a type of type Type{Int}
Julia is based on multiple dispatch, and there are circumstances where you
want to dispatch on a type rather than on a value's type. For instance,
consider the function `zero`, it accepts a type and returns 0 of that type:
zero(Float64)
> 0.0
This function is defined this way:
zero(x::Type{Float64}) = 0.0
in fact, since `x` is not used, Julia allows
zero(::Type{Float64}) = 0.0
The other half of the problem is `call`. Maybe you've seen __call__ in
Python. Basically, if I have some object m of type Mixer (or whatever),
then I can support "function call overloading" this way:
call(::Mixer, a, b, c) = a+b+c
m(1,2,3)
> 6
This is useful to define objects that behave like functions (eg. functors)
If you put both function call overloading and Type{Complex} together, you
get a way to define constructors. In Julia, each type definition
automatically defines a method of `call`, like this:
call(::Type{Complex}, re::Real, im::Real) = ...
Since `Complex` is of type `Type{Complex}`,
Complex(1,2)
will call that method. And this is how constructors work in Julia.
Cédric
On Tuesday, December 22, 2015 at 9:32:58 AM UTC-5, kleinsplash wrote:
>
> Thanks. Though its more this ::Type{Complex{T<:Real}} that is confusing
> me.. what does it mean? Is ::Type{} casting a Complex number? So do you
> then have to say something like Complex(self, realpart, imagpart)?
>
>
> On Tuesday, 22 December 2015 16:27:36 UTC+2, Jeffrey Sarnoff wrote:
>>
>> Think of Complex as complex number factory. As with any factory, this
>> one takes in some raw material, one or two numbers that are some subtype of
>> Real, and produces its product -- a Complex number.
>> And this makes sense mathematically; Real numbers are 'real number part'
>> of Complex numbers, so we expect Complex(5) to be the Complex number with a
>> real number part of 5 and an imaginary number part of 0:
>>
>> julia> Complex(5)
>> 5 + 0im
>>
>> Using two Real numbers, one for real part of the Complex number and the
>> other for imaginary part also makes sense because once we isolate the real
>> and imaginary parts, this happens:
>>
>> julia> a = Complex(5,4); a, typeof(a)
>> 5 + 4im, Complex{Int64} # or Complex{Int32}, depending on your system
>> julia> firstnumber,secondnumber = a.re, a.im
>> (5,4)
>> julia> typeof(firstnumber), typeof(secondnumber)
>> Int64, Int64
>>
>> and Integers are a subtype of Real
>> Try the same steps using 5.0 and 4.0
>>
>>
>>
>>
>>
>> On Tuesday, December 22, 2015 at 7:49:19 AM UTC-5, kleinsplash wrote:
>>>
>>> Hi,
>>>
>>>
>>> I am working through a tutorial and have come across this line:
>>>
>>>
>>> call{T<:Real}(::Type{Complex{T<:Real}}, re::T<:Real, im::T<:Real) at
>>> complex.jl:4
>>>
>>> when running:
>>>
>>>
>>> methods(Complex)
>>>
>>> I think it says:
>>>
>>>
>>> when calling Complex() you can provide two inputs either a value T which
>>> must be a subtype of type abstract type Real OR ??
>>>
>>>
>>> So an example would be:
>>>
>>>
>>> Complex(10) or Complex(5,1)
>>>
>>>
>>> Is this correct?
>>>
>>>
>>> -Thank you
>>>
>>>