-
Why is
Union{} <: Tuple
? -
When
Base.Broadcast._broadcast_eltype
returnsUnion{}
, what does that mean? That it could not infer an eltype?
On v"0.6.0"
.
Why is Union{} <: Tuple
?
When Base.Broadcast._broadcast_eltype
returns Union{}
, what does that mean? That it could not infer an eltype?
On v"0.6.0"
.
Union{}
was originally None
, renamed in Julia 0.4 (https://github.com/JuliaLang/julia/issues/8423). In Julia’s type hierarchy, this is a “bottom” type: Union{} <: T
is true
for every type T
, so it is at the “bottom” of the type hierarchy. (In fact, Base.Bottom
is an alias for Union{}
.)
My understanding is that having a bottom type made various things easier, e.g. the promotion machinery: https://github.com/JeffBezanson/phdthesis/blob/876be73a5aab9b034fac3eb9ea9d8f96713f786f/chap5.tex … it gives the type system the algebraic structure of a lattice, which makes it easier to reason about (https://github.com/JeffBezanson/phdthesis/blob/876be73a5aab9b034fac3eb9ea9d8f96713f786f/chap3.tex).
Thanks! I missed the renaming.
The issue came up when defining
"""
fixed_tuple_fields(T)
When `T` is a `Tuple{...}` with a nonzero, fixed number of elements (ie no
`Vararg`), return those; in all other cases `()`.
"""
fixed_tuple_fields(T::Type{<:Tuple}) =
(T.parameters[end] <: Vararg) ? () : tuple(T.parameters...)
How can I define this method so that it is defined for all “proper” Tuple
s, but not Union{}
?
Regarding the second question: it seems like Union{}
is returned as an inferred type when the function does not return on any path. Eg
julia> foo(x) = error("all paths lead to an error")
foo (generic function with 1 method)
julia> Base._return_type(foo, Int)
Union{}
Is this correct?
Correct. Consider the following:
(a ? foo() : bar())
what’s the inferred type of that whole expression? Well it’s the union of whatever foo returns (let’s take Union{}
) and whatever bar returns (say Int
). I.e. it’s Union{Union{}, Int}
and by standard type system rules:
julia> Union{Union{}, Int}
Int64