# Is that an issue in promote()?

**URL:** <https://discourse.julialang.org/t/is-that-an-issue-in-promote/35446>\
**Category:** General Usage\
**Created:** [March 3, 2020, 9:21am UTC](https://discourse.julialang.org/t/is-that-an-issue-in-promote/35446 "2020-03-03T09:21:11Z")\
**Posts on this page:** 14\
**Page:** 1

<div class="post-metadata">

**Author:** ![Mikhail\_Kagalenko](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mikhail_kagalenko/32/13257_2.png) [@Mikhail\_Kagalenko](https://discourse.julialang.org/u/Mikhail_Kagalenko)\
**Post date:** [March 3, 2020, 9:21am UTC](https://discourse.julialang.org/t/is-that-an-issue-in-promote/35446/1 "2020-03-03T09:21:11Z")

</div>

```julia
julia> promote(1,missing)
ERROR: promotion of types Int64 and Missing failed to change any arguments
Stacktrace:
 [1] error(::String, ::String, ::String) at ./error.jl:42
 [2] sametype_error(::Tuple{Int64,Missing}) at ./promotion.jl:306
 [3] not_sametype(::Tuple{Int64,Missing}, ::Tuple{Int64,Missing}) at ./promotion.jl:300
 [4] promote(::Int64, ::Missing) at ./promotion.jl:283
 [5] top-level scope at REPL[1]:1

julia> Base._promote(1,missing)
(1, missing)

julia> versioninfo()
Julia Version 1.3.1
Commit 2d5741174c (2019-12-30 21:36 UTC)
Platform Info:
  OS: Linux (x86_64-pc-linux-gnu)
  CPU: Intel(R) Core(TM) i3 CPU 540 @ 3.07GHz
  WORD_SIZE: 64
  LIBM: libopenlibm
  LLVM: libLLVM-6.0.1 (ORCJIT, westmere)
Environment:
  JULIA_NUM_THREADS = 8

```

---

<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:** [March 3, 2020, 9:31am UTC](https://discourse.julialang.org/t/is-that-an-issue-in-promote/35446/2 "2020-03-03T09:31:01Z")

</div>

What do you think the issue is? Those two have no (non-`Union`) common type they can be converted to.

---

<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:** [March 3, 2020, 9:48am UTC](https://discourse.julialang.org/t/is-that-an-issue-in-promote/35446/3 "2020-03-03T09:48:27Z")

</div>

Before that check was added, `promote` was far and away the most common source of StackOverflowErrors:

```julia
some_math_operation(x::T, y::T) where T<:Number = ...
some_math_operation(x, y) = some_math_operation(promote(x, y)...)

```

If `promote(x, y)` didn’t check for a change in any argument types, the second of these would call itself in an infinite loop. StackOverflowErrors are nasty (sometimes very slow to resolve, sometimes they corrupt more than you’d like), so it’s much better to have it error immediately.

---

<div class="post-metadata">

**Author:** ![Mikhail\_Kagalenko](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mikhail_kagalenko/32/13257_2.png) [@Mikhail\_Kagalenko](https://discourse.julialang.org/u/Mikhail_Kagalenko)\
**Post date:** [March 3, 2020, 10:18am UTC](https://discourse.julialang.org/t/is-that-an-issue-in-promote/35446/4 "2020-03-03T10:18:01Z")

</div>

So if I want to call promote() on the elements of the array, leaving missing values alone, would calling Base.\_promote()[1] be the recommended way, or rather an explicit implementation like

```julia
my_promote(x::T, y::S) where {T,S} = begin
    R = promote_type(T, S)
    return convert(R, x)
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:** [March 3, 2020, 10:49am UTC](https://discourse.julialang.org/t/is-that-an-issue-in-promote/35446/5 "2020-03-03T10:49:11Z")

</div>

> [@Mikhail\_Kagalenko](#):
>
> elements of the array, leaving missing values alone

It would be useful to have some context on the problem — what are you trying to do? You may not need to promote manually at all.

---

<div class="post-metadata">

**Author:** ![Mikhail\_Kagalenko](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mikhail_kagalenko/32/13257_2.png) [@Mikhail\_Kagalenko](https://discourse.julialang.org/u/Mikhail_Kagalenko)\
**Post date:** [March 3, 2020, 1:05pm UTC](https://discourse.julialang.org/t/is-that-an-issue-in-promote/35446/6 "2020-03-03T13:05:40Z")

</div>

Assume that I know what I need to do.

---

<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:** [March 3, 2020, 1:44pm UTC](https://discourse.julialang.org/t/is-that-an-issue-in-promote/35446/7 "2020-03-03T13:44:08Z")

</div>

That doesn’t sound great because you’ll only convert pairwise, which is no guarantee that all types will be the same. I’d consider a function with body something like

```julia
T = Union{}
for a in A
    ismissing(a) && continue
    T = promote_type(T, typeof(a))
end

```

and then convert the entire thing to `Array{Union{T,Missing},N}`.

---

<div class="post-metadata">

**Author:** ![Mikhail\_Kagalenko](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mikhail_kagalenko/32/13257_2.png) [@Mikhail\_Kagalenko](https://discourse.julialang.org/u/Mikhail_Kagalenko)\
**Post date:** [March 3, 2020, 1:51pm UTC](https://discourse.julialang.org/t/is-that-an-issue-in-promote/35446/8 "2020-03-03T13:51:57Z")

</div>

It is a reduce-type operation, with accumulator value promoted as the array is processed, rather than the whole array converted at once. Skipping of the missing values is done elsewhere.

---

<div class="post-metadata">

**Author:** ![Oscar\_Smith](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oscar_smith/32/25343_2.png) [@Oscar\_Smith](https://discourse.julialang.org/u/Oscar_Smith)\
**Post date:** [March 3, 2020, 2:06pm UTC](https://discourse.julialang.org/t/is-that-an-issue-in-promote/35446/9 "2020-03-03T14:06:04Z")

</div>

Is there a reason you aren’t using `foldl` or similar? This sounds like a problem base Julia can deal with well.

---

<div class="post-metadata">

**Author:** ![Mikhail\_Kagalenko](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mikhail_kagalenko/32/13257_2.png) [@Mikhail\_Kagalenko](https://discourse.julialang.org/u/Mikhail_Kagalenko)\
**Post date:** [March 3, 2020, 2:07pm UTC](https://discourse.julialang.org/t/is-that-an-issue-in-promote/35446/10 "2020-03-03T14:07:52Z")

</div>

This is the function to be supplied to mapreduce as the first argument.

---

<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:** [March 3, 2020, 2:50pm UTC](https://discourse.julialang.org/t/is-that-an-issue-in-promote/35446/11 "2020-03-03T14:50:37Z")

</div>

Well, it sounds like you know what to do for whatever it is you’re trying to do. The bottom line is that, no, `promote` isn’t broken, and yes, you’re allowed to call `promote_type` yourself and do whatever you want with the answer.

---

<div class="post-metadata">

**Author:** ![Mikhail\_Kagalenko](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mikhail_kagalenko/32/13257_2.png) [@Mikhail\_Kagalenko](https://discourse.julialang.org/u/Mikhail_Kagalenko)\
**Post date:** [March 3, 2020, 2:54pm UTC](https://discourse.julialang.org/t/is-that-an-issue-in-promote/35446/12 "2020-03-03T14:54:39Z")

</div>

So is it better to partially reimplement Base.\_promote [like this](https://discourse.julialang.org/t/is-that-an-issue-in-promote/35446/4), or call the internal function itself?

---

<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:** [March 3, 2020, 2:56pm UTC](https://discourse.julialang.org/t/is-that-an-issue-in-promote/35446/13 "2020-03-03T14:56:00Z")

</div>

It’s usually best to stick with the documented & supported interface, there is no guarantee that internals won’t change.

---

<div class="post-metadata">

**Author:** ![tkluck](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tkluck/32/15769_2.png) [@tkluck](https://discourse.julialang.org/u/tkluck)\
**Post date:** [March 3, 2020, 4:01pm UTC](https://discourse.julialang.org/t/is-that-an-issue-in-promote/35446/14 "2020-03-03T16:01:56Z")

</div>

> [@Mikhail\_Kagalenko](#):
>
> Assume that I know what I need to do.

People here including @Tamas_Papp are trying to help; I don’t think it was necessary to shut down his question like that.
