<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On Mon, Jun 26, 2017 at 6:14 PM, Juan Nunez-Iglesias <span dir="ltr"><<a href="mailto:jni.soma@gmail.com" target="_blank">jni.soma@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">



<div>
<div name="messageBodySection" style="font-size:14px;font-family:-apple-system,BlinkMacSystemFont,sans-serif">OMG deprecating + would be a nightmare. I can’t even begin to count the number of times I’ve used e.g. np.sum(arr == num)… Originally with a dtype cast but generally I’ve removed it because it worked.
<div><br></div>
<div>… But I just saw the behaviour of `sum` is different from that of adding arrays together (where it indeed means `or`), which I agree is confusing. As long as the sum and mean behaviours are unchanged, I won’t raise too much of a fuss. =P</div>
<div><br></div>
<div>Generally, although one might expect xor, what *I* would expect is for the behaviour to match the Python bool type, which is not the case right now. So my vote would be to modify ***in NumPy 2.0*** the behaviour of + and - to match Python’s built-in bool (ie upcasting to int). </div>
<div><br></div>
<div>And, in general, I’m in favour of something as foundational as NumPy, in version 1.x, to follow semantic versioning and not break APIs until 2.x.</div><span class="HOEnZb"><font color="#888888">
<div><br></div>
<div>Juan.</div>
</font></span></div>
<div name="messageReplySection" style="font-size:14px;font-family:-apple-system,BlinkMacSystemFont,sans-serif"><div><div class="h5"><br>
On 27 Jun 2017, 9:25 AM +1000, Nathaniel Smith <<a href="mailto:njs@pobox.com" target="_blank">njs@pobox.com</a>>, wrote:<br>
</div></div><blockquote type="cite" style="margin:5px 5px;padding-left:10px;border-left:thin solid #1abc9c"><div><div class="h5">On Sun, Jun 25, 2017 at 9:45 AM, Stefan van der Walt<br>
<<a href="mailto:stefanv@berkeley.edu" target="_blank">stefanv@berkeley.edu</a>> wrote:<br>
<blockquote type="cite" style="margin:5px 5px;padding-left:10px;border-left:thin solid #e67e22">Hi Chuck<br>
<br>
On Sun, Jun 25, 2017, at 09:32, Charles R Harris wrote:<br>
<br>
<blockquote type="cite" style="margin:5px 5px;padding-left:10px;border-left:thin solid #3498db">The boolean binary '-' operator was deprecated back in NumPy 1.9 and changed<br>
to an error in 1.13. This caused a number of failures in downstream<br>
projects. The choices now are to continue the deprecation for another couple<br>
of releases, or simply give up on the change. For booleans, `a - b` was<br>
implemented as `a xor b`, which leads to the somewhat unexpected identity `a<br>
- b == b - a`, but it is a handy operator that allows simplification of some<br>
functions, `numpy.diff` among therm. At this point I'm inclined to give up<br>
on the deprecation and retain the old behavior. It is a bit impure but<br>
perhaps we can consider it a feature rather than a bug.<br></blockquote>
<br>
<br>
What was the original motivation behind the deprecation? `xor` seems like<br>
exactly what one would expect when subtracting boolean arrays.<br>
<br>
But, in principle, I'm not against the deprecation (we've had to fix a few<br>
problems that arose in skimage, but nothing big).<br></blockquote>
<br>
I believe that this happened as part of a review of the whole<br>
arithmetic system for np.bool_. Traditionally, we have + is "or",<br>
binary - is "xor", and unary - is "not".<br>
<br>
Here are some identities you might expect, if 'a' and 'b' are np.bool_ objects:<br>
<br>
a - b = a + (-b)<br>
a + b - b = a<br>
bool(a + b) = bool(a) + bool(b)<br>
bool(a - b) = bool(a) - bool(b)<br>
bool(-a) = -bool(a)<br>
<br>
But in fact none of these identities hold. Furthermore, the np.bool_<br>
arithmetic operations are all confusing synonyms for operations that<br>
could be written more clearly using the proper boolean operators |, ^,<br>
~, so they violate TOOWTDI. So I think the general idea was to<br>
deprecate all of this nonsense.<br>
<br>
It looks like what actually happened is that binary - and unary - got<br>
deprecated a while back and are now raising errors in 1.13.0, but +<br>
did not. This is sort of unfortunate, because binary - is the only one<br>
of these that's somewhat defensible (it doesn't match the builtin bool<br>
type, but it does at least correspond to subtraction in Z/2, so<br>
identities like 'a - (b - b) = a' do hold).<br>
<br></div></div></blockquote></div></div></blockquote><div><br></div><div>That's because xor corresponds to addition in Z/2 and every element is its own additive inverse.<br> <br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div><div name="messageReplySection" style="font-size:14px;font-family:-apple-system,BlinkMacSystemFont,sans-serif"><blockquote type="cite" style="margin:5px 5px;padding-left:10px;border-left:thin solid #1abc9c"><div><div class="h5">
I guess my preference would be:<br>
1) deprecate +<br>
2) move binary - back to deprecated-but-not-an-error<br>
3) fix np.diff to use logical_xor when the inputs are boolean, since<br>
that seems to be what people expect<br>
4) keep unary - as an error<br>
<br>
And if we want to be less aggressive, then a reasonable alternative would be:<br>
1) deprecate +<br>
2) un-deprecate binary -<br>
3) keep unary - as an error<br>
<br></div></div></blockquote></div></div></blockquote></div><br></div><div class="gmail_extra">Using '+' for 'or' and '*' for 'and' is pretty common and the variation of '+' for 'xor' was common back in the day because 'and' and 'xor' make boolean algebra a ring, which appealed to mathematicians as opposed to everyone else ;) You can see the same progression in measure theory where eventually intersection and xor (symmetric difference) was replaced with union and complement. Using '-' for xor is something I hadn't seen outside of numpy, but I suspect it must be standard somewhere.  I would leave '*' and '+' alone, as the breakage and inconvenience from removing them would be significant.<br><br></div><div class="gmail_extra">Chuck<br></div></div>