[Numpy-discussion] Adding to the non-dispatched implementation of NumPy methods
Marten van Kerkwijk
m.h.vankerkwijk at gmail.com
Sun Apr 28 20:14:16 EDT 2019
Thanks, I now see your point. I think I can weasel my way partially out:
the default *output* from `np.concatenate` is an ndarray, so in that
respect it is not that strange that when no input defines
__array_function__, one would call `ndarray.__array_function__` (I realize
this is sophistry and that it breaks down with all-scalar functions, but
still feel it is defensible...).
Your point about `__skipping_array_function__` is well taken, though: it is
not very logical since suddenly one again ignores items that define
__array_function__. Its real purpose is to be a useful crutch if one wants
to start to define __array_function__ on one's class. But arguably this is
yet more reason to just stick with __wrapped__ - i.e., be explicit that it
is an implementation detail.
All the best,
On Sun, Apr 28, 2019 at 6:50 PM Nathaniel Smith <njs at pobox.com> wrote:
> On Sun, Apr 28, 2019 at 1:38 PM Marten van Kerkwijk
> <m.h.vankerkwijk at gmail.com> wrote:
> > Hi Nathaniel,
> > I'm a bit confused why` np.concatenate([1, 2], [3, 4])` would be a
> problem. In the current model, all (numpy) functions fall back to
> `ndarray.__array_function__`, which does know what to do with anything that
> doesn't have `__array_function__`: it just coerces it to array. Am I
> missing something?
> IMO, the reason that having ndarray.__array_function__ was attractive
> in the first place, was that we were hoping it would let you pretend
> that there's nothing special about ndarray. Like, when you call
> np.concatenate, it just looks for __array_function__ methods and
> dispatches to them; sometimes that means calling
> thirdpartyobject.__array_function__, and sometimes it means calling
> ndarray.__array_function__, but as far as np.concatenate is concerned
> those are interchangeable and treated in the same way.
> But in fact ndarray.__array_function__ *is* special. I guess you could
> write down the semantics so that np.concatenate([1, 2], [3, 4]) still
> calls ndarray.__array_function__, by defining a special dispatch rules
> just for ndarray.__array_function__. But if ndarray.__array_function__
> isn't going to follow the same dispatch rule, then why should it exist
> and be called "__array_function__"? A special method like
> "__array_function__" is nothing except a name for a dispatch rule.
> And if we add __skipping_array_function__, it makes this even worse.
> In a model where dispatch always goes through *some* object's
> __array_function__, then __skipping_array_function__ makes no sense --
> if you skip __array_function__ then there's nothing left.
> You might try to save it by saying, ok, we'll only skip third-party
> __array_function__, but still dispatch to ndarray.__array_function__.
> But this doesn't work either.
> np.concatenate.__skipping_array_function__(...) is different from
> ndarray.__array_function__(np.concatenate, ...), because they treat
> arguments with __array_function__ methods differently. (The former
> coerces them to ndarray; the latter returns NotImplemented.) Neither
> can be implemented in terms of the other (!).
> ndarray.__array_function__ was a nice idea, but I don't think there's
> any way to fit into a coherent system.
> Nathaniel J. Smith -- https://vorpus.org
> NumPy-Discussion mailing list
> NumPy-Discussion at python.org
-------------- next part --------------
An HTML attachment was scrubbed...
More information about the NumPy-Discussion