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

Proposal: empty-var args should dispatch to most general method #42222

Open
oxinabox opened this issue Sep 12, 2021 · 2 comments
Open

Proposal: empty-var args should dispatch to most general method #42222

oxinabox opened this issue Sep 12, 2021 · 2 comments
Labels
breaking This change will break code speculative Whether the change will be implemented is speculative types and dispatch Types, subtyping and method dispatch

Comments

@oxinabox
Copy link
Contributor

This is a proposal for consideration for whenever we get around to Julia 2.0.
Writing it here so it is not lost to time.
This would resolve #24315 (though that issue is labelled [docs] so I am making a new one for a non-docs based solution.)

In julia the normal rule of dispatch is to the most specific method.
This even applies when that method becomes the most specific due to having varargs, and when those varargs are not passed:

julia> bar(xs::Int...) = 1
bar (generic function with 1 method)

julia> bar(xs...) = 2
bar (generic function with 2 methods)

julia> bar()
1

Now there are a few options for how to resolve this (when we are considering that breaking is an option).

  1. As we currently do: empty-varargs go to most specific method, even if we have not passed in any of them.
  2. Change Vararg so it only matches 1+ arguments.
  3. Make this an ambiguity error
  4. Dispatch to most general vararg constraint (this proposal)

I would like to make the argument that empty varargs should always go to the most general way of meeting that constraint.
Inverting the normal rules.
The reason for this is not so complex:
The whole motivation of adding a dispatch with a specific type, is that you can use insights based on knowing your object has that type to write a better method.
For some definition of better: whether faster, more correct, etc.
But if you are given no actual instance of your type, then there is no way you have an additional insight -- if you did that insight would be applicable in every case no matter the argument type, so i would expect it to be in the more general method that already existed before you brought up your type.
And this change would allow that method to be hit.

The downside is this is another rule to remember, and implement.
The upside is it would remove a lot of cases of accidental type-piracy.
And doesn't introduce more ambiguity errors, nor require writing extra methods.

@stevengj
Copy link
Member

stevengj commented Oct 1, 2021

See #42455 for a more general, less-breaking variant of this. For the particular case above, you could define bar(xs::VarargOne{Int,Int,N}) where {N} = 1 in my proposal to require at least 1 Int argument.

@stevengj stevengj added breaking This change will break code speculative Whether the change will be implemented is speculative types and dispatch Types, subtyping and method dispatch labels Oct 1, 2021
@vtjnash
Copy link
Member

vtjnash commented Apr 29, 2022

Duplicate of #795

@vtjnash vtjnash marked this as a duplicate of #795 Apr 29, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
breaking This change will break code speculative Whether the change will be implemented is speculative types and dispatch Types, subtyping and method dispatch
Projects
None yet
Development

No branches or pull requests

3 participants