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