<div dir="ltr"><div>Hi Nathaniel,<br></div><div><br></div><div>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...).<br></div><div><br></div><div>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.</div><div><br></div><div>All the best,</div><div><br></div><div>Marten<br></div><div><br></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Sun, Apr 28, 2019 at 6:50 PM Nathaniel Smith <<a href="mailto:njs@pobox.com">njs@pobox.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">On Sun, Apr 28, 2019 at 1:38 PM Marten van Kerkwijk<br>
<<a href="mailto:m.h.vankerkwijk@gmail.com" target="_blank">m.h.vankerkwijk@gmail.com</a>> wrote:<br>
><br>
> Hi Nathaniel,<br>
><br>
> 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?<br>
<br>
IMO, the reason that having ndarray.__array_function__ was attractive<br>
in the first place, was that we were hoping it would let you pretend<br>
that there's nothing special about ndarray.  Like, when you call<br>
np.concatenate, it just looks for __array_function__ methods and<br>
dispatches to them; sometimes that means calling<br>
thirdpartyobject.__array_function__, and sometimes it means calling<br>
ndarray.__array_function__, but as far as np.concatenate is concerned<br>
those are interchangeable and treated in the same way.<br>
<br>
But in fact ndarray.__array_function__ *is* special. I guess you could<br>
write down the semantics so that np.concatenate([1, 2], [3, 4]) still<br>
calls ndarray.__array_function__, by defining a special dispatch rules<br>
just for ndarray.__array_function__. But if ndarray.__array_function__<br>
isn't going to follow the same dispatch rule, then why should it exist<br>
and be called "__array_function__"? A special method like<br>
"__array_function__" is nothing except a name for a dispatch rule.<br>
<br>
And if we add __skipping_array_function__, it makes this even worse.<br>
In a model where dispatch always goes through *some* object's<br>
__array_function__, then __skipping_array_function__ makes no sense --<br>
if you skip __array_function__ then there's nothing left.<br>
<br>
You might try to save it by saying, ok, we'll only skip third-party<br>
__array_function__, but still dispatch to ndarray.__array_function__.<br>
But this doesn't work either.<br>
np.concatenate.__skipping_array_function__(...) is different from<br>
ndarray.__array_function__(np.concatenate, ...), because they treat<br>
arguments with __array_function__ methods differently. (The former<br>
coerces them to ndarray; the latter returns NotImplemented.) Neither<br>
can be implemented in terms of the other (!).<br>
<br>
ndarray.__array_function__ was a nice idea, but I don't think there's<br>
any way to fit into a coherent system.<br>
<br>
-n<br>
<br>
-- <br>
Nathaniel J. Smith -- <a href="https://vorpus.org" rel="noreferrer" target="_blank">https://vorpus.org</a><br>
_______________________________________________<br>
NumPy-Discussion mailing list<br>
<a href="mailto:NumPy-Discussion@python.org" target="_blank">NumPy-Discussion@python.org</a><br>
<a href="https://mail.python.org/mailman/listinfo/numpy-discussion" rel="noreferrer" target="_blank">https://mail.python.org/mailman/listinfo/numpy-discussion</a><br>
</blockquote></div>