<div dir="ltr"><div class="gmail_quote"><div dir="ltr">On Tue, Jun 5, 2018 at 12:35 PM Marten van Kerkwijk <<a href="mailto:m.h.vankerkwijk@gmail.com">m.h.vankerkwijk@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div><div><div><div>Things would, I think, make much more sense if `ndarray.__array_ufunc__` (or `*_function__`) actually *were* the implementation for array-only. But while that is something I'd like to eventually get to, it seems out of scope for the current discussion.</div></div></div></div></div></blockquote><div><br></div><div>If this is a desirable end-state, we should at least consider it now while we are designing the __array_function__ interface.</div><div><br></div><div>With the current proposal, I think this would be nearly impossible. The challenge is that ndarray.__array_function__ would somehow need to call the non-overloaded version of the provided function provided that no other arguments overload __array_function__. However, currently don't expose this information in any way.</div><div><br></div><div>Some ways this could be done (including some of your prior suggestions):</div><div>- Add a coerce=True argument to all NumPy functions, which could be used by non-overloaded implementations.</div><div>- A separate namespace for non-overloaded functions (e.g., numpy.array_only).</div><div>- Adding another argument to the __array_function__ interface to explicitly provide the non-overloaded implementation (e.g., func_impl).</div><div> <br></div><div>I don't like any of these options and I'm not sure I agree with your goal, but the NEP should make clear that we are precluding this possibility.</div><div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div><div><div></div>Given that, I think that perhaps it is also best not to do `NotImplementedButCoercible` - as I think the implementers of `__array_function__` perhaps should just do that themselves. But I may well swing the other way again... Good examples of non-trivial benefits would help.</div></div></div></blockquote><div><br></div><div>This would also be my default stance, and of course we can always add NotImplementedButCoercible later.</div><div><br></div><div>I can think of two main use cases:</div><div>1. Libraries that only want to overload *some* NumPy functions, but want the rest of NumPy's API by coercing arguments to NumPy arrays.</div><div>2. Library that want to eventually overload all of NumPy's high level API, but need to do so incrementally, in a way that preserves backwards compatibility.</div><div><br></div><div>I'm not sure I agree with use case 1. Arguably, libraries that only overload a limited part of NumPy's API shouldn't encourage their users their users to rely on it. This state of affairs is pretty confusing to users.</div><div><br></div><div>However, case 2 is valid and potentially important. Consider the case of a library with existing users that would like to start implementing __array_function__ (e.g., dask, astropy, xarray, pandas). The right strategy really depends upon whether the library considers the current behavior of NumPy functions on their objects (silent coercion to numpy arrays) a feature or a bug:</div><div>- If coercion is a bug and something that the library never intended to support, then perhaps it would be OK to suddenly change all existing overloads to return the correct type.</div><div>- However, if coercion is a feature (which is probably the attitude of at least some users), ideally there really should be a graceful way to enable the new overloaded behavior incrementally. For example, a library might want to start issuing FutureWarning in version X, before switching over to the new overloaded behavior in version X+1. I can't think of how to do this without NotImplementedButCoercible.</div><div><br></div><div>For projects like dask and xarray, the benefits of __array_function__ are so large that we will accept a hard transition that breaks some user code without warning. But this may not be the case for other projects.</div></div></div>