See also 
http://docs.julialang.org/en/release-0.3/manual/faq/#how-do-abstract-or-ambiguous-fields-in-types-interact-with-the-compiler

--Tim

On Wednesday, May 06, 2015 11:20:30 PM Kevin Squire wrote:
> To add a little detail to Mauro's response:
> 
> The "overly-specific types" suggestion really applies to functions, not
> types.  That is because a different version of every function is generated
> based on the types of the arguments (as described at the end of the section
> you linked to).  The main reason to add type annotations to functions is to
> restrict the types of the parameters, which can sometimes be useful, but is
> often unnecessary (and as described in that link, can make for less generic
> code).
> 
> I'll give my answers your questions below, but if you haven't done so yet,
> I would suggest a long read through the manual to help understand these
> issues.
> 
> > *Questions*
> > 
> > > *1)* Is there any reason to define fieldtypes instead leaving fields
> > > with
> > > no type annotation?
> 
> Any field of a type which itself does not have a concrete type will be
> "boxed"--essentially, stored as a pointer with type information.  That
> makes it very difficult to generate fast code for compound objects of this
> type, because the compiler doesn't know the type of that field a compile
> time, and unlike functions, it doesn't automatically specialize the type
> based on the field types.
> 
> So, it will always work, but without concrete types for the fields, the
> compiler always has to generate extra code to check the type of the field,
> and then generate code which will do the right thing for the discovered
> type.  Whereas, with typed fields, the compiler knows the type of the field
> at compile time, and can compile fast code immediately.
> 
> > > *2) *How much performance do I sacrifice by defining a field as *Any*
> > 
> > instead
> > 
> > > of *Array  *or instead of Array{Float64,2}  or Array{Number,2}?
> 
> For functions, nothing.  For types, see the answer to 1 above.  A real
> answer depends on what you want to do, and could range from "not much
> effect" (e.g., if you're working with a struct defining a GUI interface) to
> "won't work at all" (e.g., if you're trying to call a BLAS function on an
> Array{Number,2})
> 
> > > *3)* suppose I define:
> > > 
> > > type Mytype
> > > 
> > >        a:: Array{Number,1}
> > >        b:: Array
> > >        c
> > >        end
> > > 
> > > then I create an object by
> > > 
> > > *var=Mytype( [1;2] , [1;2], [1;2] )*
> > > 
> > > julia> typeof(var.a)
> > > Array{Number,1}
> > > 
> > > julia> typeof(var.b)
> > > Array{Int64,1}
> > > 
> > > julia> typeof(var.c)
> > > Array{Int64,1}
> > > 
> > > 
> > > Why field a is Array{Number,1} while b and c is Array{Int64,1} ? Isn't
> > > Number generic enough to be turned into Int64?
> 
> First, to repeat what I said above, functions are specialized based on the
> types of their arguments, but types are not--they are only specialized if
> the type is parameterized
> <http://julia.readthedocs.org/en/latest/manual/types/#man-parametric-types)>
> !
> 
> Given that, the types of the fields of Mytype as you defined it are always
> 
> julia> Mytype.types
> (Array{Number,1},Array{T,N},Any)
> 
> where
> 
>    - Array{Number,1} is a concrete type with abstract elements.
>    - Array === Array{T,N} is an abstract type
>    - Any is also an abstract type.
> 
> So, val.a has to have the concrete type Array{Number,1}, and val.b and val.c
> must be values with types which are subtypes of Array and Any respectively.
> 
> It's also useful to know that, when you construct a type, Julia converts
> the parameters to the correct type, if necessary.  For var.b and var.c, no
> conversion is necessary, since typeof([1;2]) == Array{Int64,1} is a subtype
> of both Array{T,N} and Any (in Julia).
> 
> julia> typeof([1;2])
> Array{Int64,1}
> 
> julia> Array{Int64,1} <: Array
> true
> 
> However for the first field, Array{Int64,1} is *not* a subtype of
> Array{Number,1}:
> 
> julia> Array{Int64,1} <: Array{Number,1}
> false
> 
> So [1;2] is converted to an Array{Number,1}, and then stored.  (For this
> last point, see
> http://julia.readthedocs.org/en/release-0.3/manual/types/#parametric-composi
> te-types )
> 
> If any of this is confusing (and it quite probably is), I recommend reading
> the Julia manual section on types
> <http://julia.readthedocs.org/en/release-0.3/manual/types/>, as well
> as the Wikipedia
> article on Covariance and Contravariance
> <http://en.wikipedia.org/wiki/Covariance_and_contravariance_%28computer_scie
> nce%29> .
> 
> Moral: you should almost always give fields concrete types (with concrete
> subtypes), and for more flexibility, you can use parameterized types.
> 
> Cheers,
>    Kevin

Reply via email to