On Fri, Apr 26, 2019 at 12:04 AM Stephan Hoyer <shoyer@gmail.com> wrote:
On Thu, Apr 25, 2019 at 12:46 PM Marten van Kerkwijk <m.h.vankerkwijk@gmail.com> wrote:
It seems we are adding to the wishlist!  I see four so far:
1. Exposed in API, can be overridden with __array_ufunc__
2. One that converts everything to ndarray (or subclass); essentially the current implementation;
3. One that does asduckarray
4. One that assumes all arguments are arrays.

Maybe handiest would be if there is a method to coerce all relevant arguments with a function of one's choice? I.e., in the example of Stephan, one would have
if function in JUST_COERCE:
    coerced_args, coerced_kwargs = function.__coerce__(np.asanyarray, *args, **kwargs)
    return function.__implementation__(*coerced_args, **coerced_kwargs)
Actually, this might in fact work with the plan proposed here, if we allow for an extra, optional kwarg that contains the coercion function, that is
    return function.__implementation__(*args, coercion_function=np.asanyarray, **kwargs)

The possible advantage of this over yet more dunder methods is that one can fine-tune the extent to which something has to mimic an array properly (e.g., run `asanyarray` only if `shape` is not present).

I do like the look of this, but keep in mind that there is a downside to exposing the implementation of NumPy functions -- now the implementation details become part of NumPy's API. I suspect we do not want to commit ourselves to never changing the implementation of NumPy functions, so at the least this will need careful disclaimers about non-guarantees of backwards compatibility.

I honestly still am missing the point of claiming this. There is no change either way to what we've done for the last decade. If we change anything in the numpy implementation of any function, we use deprecation warnings etc. What am I missing here?

But for now, I would love to pick a name for "essentially the current implementation", which is something that would make a big difference for near-term NEP-18 use cases. Some options:

The last two are not quite right, since there is some legacy dispatching to methods. Maybe __skipping_array_function__ is the best?

imho those names are all worse than __wrapped__ or __numpy_implementation__


Whatever we pick, we can always make it an alias later, e.g., for func.__implementation__(*args, coercion_function=np.asanyarray, **kwargs).
It would be nice, though, if we could end up with also option 4 being available, if only because code that just can assume ndarray will be easiest to read.

This could perhaps just be coercion_function=None? Or maybe we want to keep around coercion_function=None for "do whatever ad-hoc coercion NumPy current does"?

All the best,

NumPy-Discussion mailing list
NumPy-Discussion mailing list