<div dir="ltr"><div dir="ltr"><br></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Mon, Sep 2, 2019 at 2:09 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 Mon, Sep 2, 2019 at 2:15 AM Hameer Abbasi <<a href="mailto:einstein.edison@gmail.com" target="_blank">einstein.edison@gmail.com</a>> wrote:<br>
> Me, Ralf Gommers and Peter Bell (both cc’d) have come up with a proposal on how to solve the array creation and duck array problems. The solution is outlined in NEP-31, currently in the form of a PR, [1]<br>
Thanks for putting this together! It'd be great to have more<br>
engagement between uarray and numpy.<br>
> ============================================================<br>
> NEP 31 — Context-local and global overrides of the NumPy API<br>
> ============================================================<br>
Now that I've read this over, my main feedback is that right now it<br>
seems too vague and high-level to give it a fair evaluation? The idea<br>
of a NEP is to lay out a problem and proposed solution in enough<br>
detail that it can be evaluated and critiqued, but this felt to me<br>
more like it was pointing at some other documents for all the details<br>
and then promising that uarray has solutions for all our problems.<br></blockquote><div><br></div><div>This is fair enough I think. We'll need to put some more thought in where to refer to other NEPs, and where to be more concrete.</div><div> <br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
> This NEP takes a more holistic approach: It assumes that there are parts of the API that need to be<br>
> overridable, and that these will grow over time. It provides a general framework and a mechanism to<br>
> avoid a design of a new protocol each time this is required.<br>
The idea of a holistic approach makes me nervous, because I'm not sure<br>
we have holistic problems. Sometimes a holistic approach is the right<br>
thing; other times it means sweeping the actual problems under the<br>
rug, so things *look* simple and clean but in fact nothing has been<br>
solved, and they just end up biting us later. And from the NEP as<br>
currently written, I can't tell whether this is the good kind of<br>
holistic or the bad kind of holistic.<br></blockquote><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
Now I'm writing vague handwavey things, so let me follow my own advice<br>
and make it more concrete with an example :-).<br>
When Stephan and I were writing NEP 22, the single thing we spent the<br>
most time discussing was the problem of duck-array coercion, and in<br>
particular what to do about existing code that does<br>
The reason this is challenging is that there's a lot of code written<br>
in Cython/C/C++ that calls np.asarray,</blockquote><div><br></div><div>Cython code only perhaps? It would surprise me if there's a lot of C/C++ code that explicitly calls into our Python rather than C API.</div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"> and then blindly casts the<br>
return value to a PyArray struct and starts accessing the raw memory<br>
fields. If np.asarray starts returning anything besides a real-actual<br>
np.ndarray object, then this code will start corrupting random memory,<br>
leading to a segfault at best.<br>
Stephan felt strongly that this meant that existing np.asarray calls<br>
*must not* ever return anything besides an np.ndarray object, and<br>
therefore we needed to add a new function np.asduckarray(), or maybe<br>
an explicit opt-in flag like np.asarray(..., allow_duck_array=True).<br>
I agreed that this was a problem, but thought we might be able to get<br>
away with an "opt-out" system, where we add an allow_duck_array= flag,<br>
but make it *default* to True, and document that the Cython/C/C++<br>
users who want to work with a raw np.ndarray object should modify<br>
their code to explicitly call np.asarray(obj, allow_duck_array=False).<br>
This would mean that for a while people who tried to pass duck-arrays<br>
into legacy library would get segfaults, but there would be a clear<br>
path for fixing these issues as they were discovered.<br>
Either way, there are also some other details to figure out: how does<br>
this affect the C version of asarray? What about np.asfortranarray –<br>
probably that should default to allow_duck_array=False, even if we did<br>
make np.asarray default to allow_duck_array=True, right?<br>
Now if I understand right, your proposal would be to make it so any<br>
code in any package could arbitrarily change the behavior of<br>
np.asarray for all inputs, e.g. I could just decide that<br>
np.asarray([1, 2, 3]) should return some arbitrary non-np.ndarray<br>
object. </blockquote><div><br></div><div>No, definitely not! It's all opt-in, by explicitly importing from `numpy.overridable` or `unumpy`. No behavior of anything in the existing numpy namespaces should be affected in any way.<br></div><div> </div><div>I agree with the concerns below, hence it should stay opt-in.</div><div><br></div><div>Cheers,<br></div><div>Ralf</div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">It seems like this has a much greater potential for breaking<br>
existing Cython/C/C++ code, and the NEP doesn't currently describe why<br>
this extra power is useful, and it doesn't currently describe how it<br>
plans to mitigate the downsides. (For example, if a caller needs a<br>
real np.ndarray, then is there some way to explicitly request one? The<br>
NEP doesn't say.) Maybe this is all fine and there are solutions to<br>
these issues, but any proposal to address duck array coercion needs to<br>
at least talk about these issues!<br>
And that's just one example... array coercion is a particularly<br>
central and tricky problem, but the numpy API big, and there are<br>
probably other problems like this. For another example, I don't<br>
understand what the NEP is proposing to do about dtypes at all.<br>
That's why I think the NEP needs to be fleshed out a lot more before<br>
it will be possible to evaluate fairly.<br>
-- <br>
Nathaniel J. Smith -- <a href="https://vorpus.org" rel="noreferrer" target="_blank">https://vorpus.org</a><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>