# Subtyping made friendly: Question about UnionAll

**URL:** <https://discourse.julialang.org/t/subtyping-made-friendly-question-about-unionall/14766>\
**Category:** 2018\
**Tags:** question\
**Created:** [September 10, 2018, 1:18pm UTC](https://discourse.julialang.org/t/subtyping-made-friendly-question-about-unionall/14766 "2018-09-10T13:18:34Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![NHDaly](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nhdaly/32/1413_2.png) [@NHDaly](https://discourse.julialang.org/u/NHDaly)\
**Post date:** [September 10, 2018, 1:18pm UTC](https://discourse.julialang.org/t/subtyping-made-friendly-question-about-unionall/14766/1 "2018-09-10T13:18:35Z")

</div>

In Francesco Zappa Nardelli’s awesome talk, [Subtyping made friendly](https://www.youtube.com/watch?v=Y95fAipREHQ&index=45&list=PLP8iPy9hna6Qsq5_-zrg0NTwqDSDYtfQB), he showed this example to motivate UnionAll types, [here](https://www.youtube.com/watch?v=Y95fAipREHQ&index=45&list=PLP8iPy9hna6Qsq5_-zrg0NTwqDSDYtfQB&t=20m30s):

 ![Subtyping made friendly: UnionAll](https://global.discourse-cdn.com/julialang/original/3X/0/d/0d16d61d833d96cb30d06f9939e98bec7b05d878.jpeg)

However, those type signatures are not exactly equivalent: the second version of `foo` also accepts `Vector{Signed}` as an argument. This could be problematic if the implementation of `foo` _depends_ on all the elements of the Vector having the same type.

Is there any way to achieve the same behavior as the original declaration without having to enumerate all the possibilities?

The behavior arises from `<:` being sort of like “less than or equal to”. Is there a way to specify a “strictly less than” version of the subtype relation for dispatch, like `<<:`?

Or perhaps some way to form the `Union` programmatically? Something like this pseudocode:

```julia
signed_types = Union{collect(Vector{T} where T <: Signed && T != Signed)...}
function foo(x::signed_types) ... end

```

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [September 10, 2018, 1:38pm UTC](https://discourse.julialang.org/t/subtyping-made-friendly-question-about-unionall/14766/2 "2018-09-10T13:38:37Z")

</div>

```julia
@assert isconcretetype(T)

```

in the function body.

---

<div class="post-metadata">

**Author:** ![NHDaly](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nhdaly/32/1413_2.png) [@NHDaly](https://discourse.julialang.org/u/NHDaly)\
**Post date:** [September 10, 2018, 1:43pm UTC](https://discourse.julialang.org/t/subtyping-made-friendly-question-about-unionall/14766/3 "2018-09-10T13:43:42Z")

</div>

That works okay, but not if I want the logic to happen during dispatch… Like, maybe I have some other generic version of `foo` I want to be called for all other types.

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [September 10, 2018, 2:03pm UTC](https://discourse.julialang.org/t/subtyping-made-friendly-question-about-unionall/14766/4 "2018-09-10T14:03:44Z")

</div>

You can do that with traits (check the type for concreteness, compute a trait, dispatch on that).

That said, it would be interesting to see a use case, perhaps there is an easier way of doing what you want.

---

<div class="post-metadata">

**Author:** ![rdeits](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rdeits/32/286_2.png) [@rdeits](https://discourse.julialang.org/u/rdeits)\
**Post date:** [September 10, 2018, 2:37pm UTC](https://discourse.julialang.org/t/subtyping-made-friendly-question-about-unionall/14766/5 "2018-09-10T14:37:34Z")

</div>

You could do the dispatch manually with an `@generated` function:

```julia
julia> @generated function f(x::Vector{T}) where {T <: Signed}
         if isconcretetype(T)
           :(f_concrete(x))
         else
           :(f_not_concrete(x))
         end
       end
f (generic function with 1 method)

julia> f_concrete(x) = "concrete"
f_concrete (generic function with 1 method)

julia> f_not_concrete(x) = "not concrete"
f_not_concrete (generic function with 1 method)

julia> f([1,2,3])
"concrete"

julia> f(Signed[1,2,3])
"not concrete"

```

Although the compiler is actually pretty smart, so the `@generated` isn’t even necessary in this case. The following works just as well:

```julia
julia> function f(x::Vector{T}) where {T <: Signed}
         if isconcretetype(T)
           f_concrete(x)
         else
           f_not_concrete(x)
         end
       end
f (generic function with 1 method)

```

Alternatively, you could use a trait:

```julia
julia> f(x::Vector{T}) where {T <: Signed} = f(x, mytrait(T))
f (generic function with 3 methods)

julia> struct ConcreteSigned; end

julia> struct NonConcreteSigned; end

julia> function mytrait(::Type{T}) where {T <: Signed}
         if isconcretetype(T)
           ConcreteSigned()
         else
           NonConcreteSigned()
         end
       end
mytrait (generic function with 2 methods)

julia> f(x::Vector{<:Signed}, ::ConcreteSigned) = "concrete"
f (generic function with 3 methods)

julia> f(x::Vector{<:Signed}, ::NonConcreteSigned) = "not concrete"
f (generic function with 3 methods)

julia> f([1,2,3])
"concrete"

julia> f(Signed[1,2,3])
"not concrete"

```

---

<div class="post-metadata">

**Author:** ![NHDaly](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nhdaly/32/1413_2.png) [@NHDaly](https://discourse.julialang.org/u/NHDaly)\
**Post date:** [September 10, 2018, 8:06pm UTC](https://discourse.julialang.org/t/subtyping-made-friendly-question-about-unionall/14766/6 "2018-09-10T20:06:17Z")

</div>

Thanks both for the great explanations!!

> [@Tamas\_Papp](#):
>
> it would be interesting to see a use case, perhaps there is an easier way of doing what you want

Ah, sorry, I don’t have one, I was simply curious about this while watching the above talk. It makes sense though I think that in most cases `isconcretetype` isn’t a necessary constraint.

Thanks!

---

<div class="post-metadata">

**Author:** ![fzn](https://avatars.discourse-cdn.com/v4/letter/f/e36b37/32.png) [@fzn](https://discourse.julialang.org/u/fzn)\
**Post date:** [September 10, 2018, 8:31pm UTC](https://discourse.julialang.org/t/subtyping-made-friendly-question-about-unionall/14766/7 "2018-09-10T20:31:15Z")

</div>

Hi all.

The example in my talk was meant to give nothing more an than intuition about the semantics of UnionAll types. The two types are not equivalent (you cannot prove the latter to be subtype of the former) and I apologize if this was source of confusion.

Btw, the solution with traits is a nice use case for the Type type construct, which turned out to be tricky to formalize correctly. If you are curious, our paper contains all the details: [Julia Subtyping: a Rational Reconstruction](https://tinyurl.com/lambdajulia) (we did our best to make it accessible to non programming-language-semantics specialists).

-francesco
