# Questions on Advanced Type Manipulation

**URL:** <https://discourse.julialang.org/t/questions-on-advanced-type-manipulation/3862>\
**Category:** General Usage\
**Created:** [May 22, 2017, 9:16pm UTC](https://discourse.julialang.org/t/questions-on-advanced-type-manipulation/3862 "2017-05-22T21:16:31Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![mohamed82008](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mohamed82008/32/18171_2.png) [@mohamed82008](https://discourse.julialang.org/u/mohamed82008)\
**Post date:** [May 22, 2017, 9:16pm UTC](https://discourse.julialang.org/t/questions-on-advanced-type-manipulation/3862/1 "2017-05-22T21:16:31Z")

</div>

I have a few questions on manipulating types:

1. What is the difference between how promote\_type and typejoin work?

2. Isn’t it inaccurate to interpret typejoin as a set union, as it is described in the documentation, when the result of `typejoin(Int8,Float64)` is Real? I mean clearly Int64 is not a subtype of Float64 or Int8 but is a subtype of Real, which is a contradiction to the set analogy.

3. What is the correct use of a lower bound type in type variables? As I read in the documentation, only leaf (non-abstract) types can be implemented, the rest are all abstract. So is there any benefit to setting an abstract type as a lower bound to a type parameter/variable, when in fact that eliminates all implementable types from the feasible set of types satisfying this condition, hence no argument can possibly match the parametric signature of the function having this type parameter/variable!? Is there another use case I am missing? And if we limit ourselves to a leaf lower bound type, can’t we just use that leaf type straight away as the type of the argument, because all its supertypes cannot be implemented anyway? Similarly, using multiple leaf types in a Union as a lower bound type, e.g. `Union{Int,Float64}` is not very useful; because we can just use the `Union{Int, Float64}` directly as the type of the argument.

4. Just to confirm my understanding, does the bound field printed when running xdump on a type’s parameters, e.g. xdump(Array.parameters), mean whether the type variable refers to a specific type to be determined based on the argument, or if it is just an arbitrary/abstract/anonymous type parameter, and all arbitrary type parameters are assumed equal? Consider the following example:  
`S = TypeVar(:S, false); T = TypeVar(:T, false); Array{S} == Array{T}`  
returns true, because S and T are both arbitrary and hence they are treated to be equal when comparing types (including type comparison to find a suitable method for the arguments). However, `S == T` returns false, which means that they are only treated as equal when used as type parameters. Someone please confirm my understanding if my explanation was clear enough.

---

<div class="post-metadata">

**Author:** ![tim.holy](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tim.holy/32/52_2.png) [@tim.holy](https://discourse.julialang.org/u/tim.holy)\
**Post date:** [May 22, 2017, 9:59pm UTC](https://discourse.julialang.org/t/questions-on-advanced-type-manipulation/3862/2 "2017-05-22T21:59:15Z")

</div>

Good questions.

1. `promote_type`’s behavior is determined by the `promote_rule`s that have been set up. In contrast, `typejoin` works abstractly, widening types using `supertype` until it contains all the input types. `typejoin` is a pretty small function, it might be instructive to inspect the source (`edit(typejoin, (Any, Any))`).

2. Which documentation are you looking at? `Union{Int8,Float64}` is genuinely a set union, but I don’t see a claim that `typejoin` is. When I type `?typejoin` I get

```julia
  Compute a type that contains both T and S.

```

1. Lower bounds are rarely used in regular code. They can be useful internally in type intersection and subtyping. But here’s an example that may help:

```julia
julia> foo{Int<:T<:Real}(::Type{T}) = 1
foo (generic function with 1 method)

julia> foo(Int)
1

julia> foo(Int8)
ERROR: MethodError: no method matching foo(::Type{Int8})
Closest candidates are:
  foo(::Type{Int64<:T<:Real}) where Int64<:T<:Real at REPL[1]:1

julia> foo(Signed)
1

```

1. Yes, I think that’s correct.

---

<div class="post-metadata">

**Author:** ![mohamed82008](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mohamed82008/32/18171_2.png) [@mohamed82008](https://discourse.julialang.org/u/mohamed82008)\
**Post date:** [May 22, 2017, 10:06pm UTC](https://discourse.julialang.org/t/questions-on-advanced-type-manipulation/3862/3 "2017-05-22T22:06:39Z")

</div>

Interesting example.

This is the documentation I was talking about [https://docs.julialang.org/en/stable/devdocs/types/](https://docs.julialang.org/en/stable/devdocs/types/)

Thanks alot for clarifying the rest.

---

<div class="post-metadata">

**Author:** ![tim.holy](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tim.holy/32/52_2.png) [@tim.holy](https://discourse.julialang.org/u/tim.holy)\
**Post date:** [May 22, 2017, 10:28pm UTC](https://discourse.julialang.org/t/questions-on-advanced-type-manipulation/3862/4 "2017-05-22T22:28:53Z")

</div>

I can see that might be confusing, but it does say “a type that contains their union”. Since `Union{Int8,Float64} <: Real` the documentation is actually correct.

---

<div class="post-metadata">

**Author:** ![mohamed82008](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mohamed82008/32/18171_2.png) [@mohamed82008](https://discourse.julialang.org/u/mohamed82008)\
**Post date:** [May 22, 2017, 10:31pm UTC](https://discourse.julialang.org/t/questions-on-advanced-type-manipulation/3862/5 "2017-05-22T22:31:53Z")

</div>

Yes, I realize now it’s my misunderstanding.
