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

Ambiguity avoidance by "at least one" syntax for argument types #10440

Closed
timholy opened this issue Mar 8, 2015 · 2 comments
Closed

Ambiguity avoidance by "at least one" syntax for argument types #10440

timholy opened this issue Mar 8, 2015 · 2 comments

Comments

@timholy
Copy link
Sponsor Member

timholy commented Mar 8, 2015

I'm trying to define some new indexing methods, and running up against ambiguity warnings. Here's what I'm trying to do:

function getindex(A::AbstractArray, index::Union(Real, SomeType)...)

I want this function to be called only if there is at least one SomeType among the index arguments; otherwise the standard methods for Real are just fine. As far as I can tell, we don't have a syntax for expressing this. Certainly,

function getindex(A::AbstractArray, index1::SomeType, index::Union(Real, SomeType)...)

insists that the first index is a SomeType, but this isn't sufficiently flexible for my needs.

How plausible would it be to implement this? As for syntax,

function getindex(A::AbstractArray, index::Union(Real, SomeType+)...)

suggests itself (regex-like). If one had multiple options, then

function getindex(A::AbstractArray, index::Union(Real, Union(SomeType1,SomeType2)+)...)

seems natural.

@JeffBezanson
Copy link
Sponsor Member

The way to do this currently is to define both of these:

getindex(A::AbstractArray, index::Union(Real, SomeType)...)

getindex(A::AbstractArray, index::Real...)

Then the first method will only be called with at least one SomeType.

This can be expressed with set operations as (Union(Real,SomeType)...) ∩ ¬(Real...). However we are not likely to have types like this. They would probably make subtyping undecidable, and are generally just very difficult to implement.

What I do plan to do is this: a method signature does not need to be a tuple of types. It can be any type that's a subtype of Tuple. So you should be able to use Union((Int,Any), (Any,Int)) as a method signature, matching cases where the first OR second argument is an Int, without ambiguities. Tantalizingly close, but appears to be not quite powerful enough for the N-ary case.

@timholy
Copy link
Sponsor Member Author

timholy commented Mar 8, 2015

I should have pointed out that I'm aware of the current strategy and use it frequently. It's just that it's particularly awkward when (1) there are several kinds of AbstractArray, and (2) we already have things likegetindex(A, index::Union(Real, AbstractVector)...) defined in base. As far as I can tell, together these mean that in packages, you often can't avoid ambiguity warnings without basically rewriting a chunk of Base, including generating specific methods for Array, SubArray, SharedArray, etc.

But, making subtyping undecidable is not exactly a direction we want to go down, so I'll close this. I suppose we should do a little bit of refactoring of Base now, though, to make this easier. Probably the only sensible definition is

getindex(A::AbstractArray, index::Real...) = getindex(A, to_index(index)...)

That will result in a stack overflow if someone forgets to define

function getindex(A::MyAbstractArray, index::Int...)

but perhaps that's the least of all evils.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants