-
Notifications
You must be signed in to change notification settings - Fork 53
Can we promise to delegate to reverse operators ? #732
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
Comments
Interesting question. The discussion you linked in numpy/numpy#9677 is quite relevant. The NumPy behavior is clearly not great, but @seberg makes a good point: Frankly, if you want to add such a promise there (which is an issue for the Array API), you better have an idea how to pull of changing it in NumPy. Saying numpy must change it is useless if it can't. The Array API does not even define a way to mix array objects, interacting with a custom object is undefined to begin with anyway. As noted in https://data-apis.org/array-api/latest/purpose_and_scope.html, subclassing of an array class is out of scope; an implementation may not even allow this. E.g., JAX doesn't seem to support it at all (jax-ml/jax#4269), and in CuPy subclassing is mostly supported since 2022 only (see cupy/cupy#3972 (comment)) and still undocumented as far as I can tell. So I suspect that the best we can do here is a note that recommends to return |
I guess I'm confused by this wrt the Array API. I understand that it's not possible to change Numpy. What's the problem with making the Array API promise this? Are there implementors that can't do it for some reason? Even NumPy's implementation of the Array API should be able to do it, right?
What do you think of the example I gave of a rectangle class? Should it be possible to write such a class and have it interact normally with the array API? |
No, the implementation is in the main namespace from 2.0 onwards - and even if that wasn't the case, it would still want to reuse the
I don't think so, no. It's not just about operator support or subclassing. It'd be very hard to see how to implement any such rectangle object that can be used with regular functions, since those only support For every arrays library in existence, custom objects like this are either unsupported or very messy. I don't see any chance of fixing that in this standard. |
Thank you for explaining. I think I understand now.
If it weren't the case, then Doesn't that mean that for
Right, now I understand this. This would be a nice start—maybe one day, we'll be able to shake off this technical debt. |
Yes, sure. That is perfectly fine though - it will implement a superset, and that doesn't impede the ability to write portable code which targets the standard. |
That was not how it is designed for better or worse. Remember, the Array API mainly targets libraries. Those get passed a NumPy array by the user and must return a NumPy array. That would be a legitimate design and I do think it would have remove some obstacles. But, it is not the current choice it looks like that is probably not a big headache. |
It does seem kind of odd to include the Note that for numpy specifically, you can work around this by making TBH, I'm a little disappointed that nothing was done about this in numpy 2.0 specifically for the case where a non-object array is promoted to an object array. That's a major source of bugs, or at worse, inscrutable error messages in my experience. I know there are some libraries like pandas that use object arrays on purpose, but requiring more explicitness about something becoming an object array would be good thing. It's inline, for instance, with the change to make ragged arrays raise an exception instead of silently becoming an object array. |
By the way, this was discussed before at #229 (comment) |
Background
Ordinary NumPy arrays have a peculiar operator behaviour:
__add__
fails, then instead of returningNotImplemented
(which would be idiomatic Python),float
orint
), and then calls the corresponding reverse operator (like__radd__
) on these elements and the RHSIt is too late for NumPy to change this since this would break a lot code.
Motivation
Consider someone implementing a class that must interact with arrays. For example, a rectangle class defined by storing the opposite corners of a rectangle. If
x = Rectange(...)
anda
is an array, we want to support bothx + a
anda + x
. If the decomposition/collation described above happens, then this will not work:a + x
will try to build an array of rectangles offset by floats.Proposal
Conformant implementations of the Array API should return
NotImplemented
when they don't know how to evaluate an operator with their arrays—rather than this behavior being implementation-defined. Also, it would be useful to have a test in the conformance test suite that verifies this.The text was updated successfully, but these errors were encountered: