Type and DataType themselves are both types. And the type of most types, as you found, is DataType . In this case, the DataType is a subtype of the abstract Type :
julia> supertype(DataType) Type{T} julia> supertype(Type) Any julia> DataType <: Type true
This means that all that isa DataType will also be Type - so many types in Julia are equal to isa . There are also other subtypes of Type , including Union and TypeConstructor s. This means that all types in julia will be of type Type , but even simple things like Vector will not be of type DataType .
Type is special. As you see above, it is parametric. This allows you to accurately indicate the type of a particular type. Therefore, although each type in Julia isa Type , only Int isa Type{Int} :
julia> isa(Int, Type{Int}) true julia> isa(Float64, Type{Int}) false julia> isa(Float64, Type) true
This ability is unique and unique to Type , and it is important to specify the dispatch for a particular type. For example, many functions allow you to specify a type as the first argument.
f(x::Type{String}) = "string method, got $x" f(x::Type{Number}) = "number method, got $x" julia> f(String) "string method, got String" julia> f(Number) "number method, got Number"
It is worth noting that Type{Number} is only a Number type, not an Int type, although Int <: Number ! This is parametric invariance. To allow all subtypes of a particular abstract type, you can use the function parameter:
julia> f(Int) ERROR: MethodError: no method matching f(::Type{Int64}) julia> f{T<:Integer}(::Type{T}) = "integer method, got $T" f (generic function with 3 methods) julia> f(Int) "integer method, got Int64"
The ability to capture a specific type as a function parameter is powerful and often used. Note that I donβt even need to specify an argument name - the only thing that matters in this case is the parameter in Type{} .
So, this was a rather long explanation of what the answer is really quite short: usually you do not want to use DataType , since it will not cover all types in Julia. Instead, you should use Type to describe the type of any or all types. Use Type{T} if you want to describe type T in particular.