The others already answered the main question:
Julia is a fully dynamic language. This means that there are no static types in julia, and the type of x
is always the same as typeof(x)
.
This is as opposed to e.g. java, where ArrayList<String> x = new ArrayList<String>();
still leaves you with x.getClass()
being ArrayList<>
; or, in other words, java types exist only on the source-code / compile-time level, while compiled code / runtime objects only have classes, and a typeof
runtime function cannot exist (because the types have been erased).
Hence, Vector{Point2d}
and Vector{Any}
are genuinely different types, and can have genuinely different memory layout, and functions can dispatch on the type parameter.
Your options for the eltype
of your Vector are:
- Concrete type, or small union of concrete types – this is fastest!
Any
– If you cannot make the type concrete or small union of concrete types, then this is normally the next fastest variant.
- Abstractly typed – stuff like
Vector{Real}
or Vector{Vector}
. In very rare instances this can perform better than Vector{Any}
, but consensus is that this is a trap. Nevertheless you may sometimes need this, especially if you then have to dispatch on the type parameter (i.e. you have foo(x::Vector{Vector})
and foo(x::Vector{T}) where T<:Real
). This is a code smell, though.
The more interesting question is how to achieve this in your example. There are two reasonable ways. You can be explicit:
v = Point2d{Int}[]
push!(v, Point2d(a,b))
#equivalent:
v = Point2d{Int}[Point2d(a,b)]
Or you can let julia’s base vector concat figure it out:
v = [Point2d(a,b)]
This is equivalent to
point = Point2d(a,b)
v = typeof(point)[point]
The difference will become apparent if you ever want to support points with Int16
or Int128
coordinates, or run automatic differentiation.
However, writing code that seamlessly supports AD or different integer sizes or Float precisions is a little bit of an art, with lots of pitfalls.
Depending on your code, you can often double (or more, if you’re cache-size bound!) your performance by dropping to Int32 and Float32, but you need to be very careful about literals (because in julia, literals are typed. In other words, x = Int32(0); x += 1; typeof(x)
is Int64
. This is a very big pitfall compared to java or C, where rvalue literals try to adopt the type of the lvalue. The julia way is very elegant in terms of language simplicity, but it makes writing some kinds of code a total pain).