I’ve recently been using a lot of Int16s, and found really unexpected behavior when I ended up plugging one of them in as a type parameter. For example:
You can’t use one to define an NTuple
julia> NTuple{2, Nothing}
Tuple{Nothing,Nothing}
julia> NTuple{Int16(2), Nothing}
ERROR: TypeError: in Vararg, in count, expected Int64, got Int16
Stacktrace:
[1] top-level scope at none:0
Which leads to problems when you have a type that contains an NTuple
julia> struct Foo{N}
x::NTuple{N,Int}
end
julia> foo64 = Foo{2}
Foo{2}
julia> foo16 = Foo{Int16(2)}
Foo{2}
julia> fieldtypes(foo64)
(Tuple{Int64,Int64},)
julia> fieldtypes(foo16)
(Union{},)
I think it would be nice if this just worked, but even if it doesn’t I think it should throw an error when I try to make the struct - I spent a bit of time before realizing what I had done, because I only noticed it when I got
julia> @assert isbitstype(foo64)
julia> @assert isbitstype(foo16)
ERROR: AssertionError: isbitstype(foo16)
Stacktrace:
[1] top-level scope at none:0
I think isbitstype
fails for you since foo16
cannot have a valid instance.
Can’t you just use an integer parameter for NTuple
?
Yeah, of course. The problem arose because my variable was an Int16 and I didn’t think to convert it before using it as a type parameter. The solution is easy, which is to convert before using it.
The problem is that Julia lets me create a Foo subtype with an Int16 parameter, but changes Tuple field to a Union{}. I should not be able to make a Foo subtype where the field is not a Tuple - either it should throw an error (like NTuple) or automatically convert to an Int
As I said above, I don’t think this the problem here. You are not “creating” a type with that parameter: types have no lifetime (in the sense values do, ie that validation can happen somewhere). For parametric types, you can pretty much do what you like, eg you can just work with
julia> T1 = AbstractArray{:nonsense,-7}
AbstractArray{:nonsense,-7}
julia> eltype(T1)
:nonsense
as a type. But there cannot be a value with that type.
Similarly, there cannot be a value with type foo16
. So Union{}
is the right anwer for its field type.
1 Like