Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

promote_op doesn't play well with Union{Missing, T} #28370

Closed
andyferris opened this issue Jul 31, 2018 · 3 comments · Fixed by #29739
Closed

promote_op doesn't play well with Union{Missing, T} #28370

andyferris opened this issue Jul 31, 2018 · 3 comments · Fixed by #29739
Labels
won't change Indicates that work won't continue on an issue or pull request

Comments

@andyferris
Copy link
Member

Sometimes I use promote_op to predict the element type of containers for non-trivial operations where the element type might change.

However, while working out how my packages might work with missing in v0.7 I came across this stumbling block:

julia> Base.promote_op(+, Int, Union{Float64, Missing})
Any

(I do realize there is a momentum to rely less on inference and more on "the type of actual elements at run-time" (at least in Base)... but sometimes the promote_op pattern is the quickest path to victory and I don't see why it shouldn't work as well as possible).

@KristofferC
Copy link
Member

From some small poking. The return type of applying + to Int and the union is computed as Union{Missing, Float64} but that is only returned if the two types and the return type are isdispatchtuple. Otherwise typejoin is called and we have:

julia> isdispatchtuple(Union{Missing, Float64})
false

julia>  typejoin(Int64, Union{Missing, Float64}, Union{Missing, Float64})
Any

@andyferris
Copy link
Member Author

andyferris commented Aug 1, 2018

Right! As you note, inference itself is precise.

julia> Core.Compiler.return_type(+, Tuple{Int, Union{Float64, Missing}})
Union{Missing, Float64}

While not quite dispatchable, I wonder if we could nonetheless add some extra logic around Union types here (or in typejoin itself)?

@vtjnash vtjnash added the won't change Indicates that work won't continue on an issue or pull request label Oct 20, 2018
@vtjnash
Copy link
Member

vtjnash commented Oct 20, 2018

I think the literal definition of this function should probably be:

Base.promote_op(op, AT::Type...) = Base.promote_type(AT..., Base._return_type(op, Tuple{AT...}))

But it's never been implemented as anything meaningfully similar to that.

Nor have any of the users of the code likely intended for it to do that.

Nor is it currently documented to do anything like that.

We've removed most users of this function, so it would seem that we're well on our way to eliminating it entirely. I'll put up a PR shortly to fix it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
won't change Indicates that work won't continue on an issue or pull request
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants