Feature #7328

Move ** operator precedence under unary + and -

Added by Boris Stitnicky over 1 year ago. Updated over 1 year ago.

[ruby-core:49211]
Status:Rejected
Priority:Normal
Assignee:-
Category:-
Target version:-

Description

I would like to ask to consider decreasing ** operator precedence just below that of -/+ unary operators. I know that other languages (eg. Python) have ** operator bind tighter than negation, but seeing -1 ** 0.5 give the result -1 and having to type parenthesis (-1) ** 0.5... Even if it's not worth changing, I'd like to hear this rationalized. I've asked about rationalization of this on SO, and nobody seems to know why this precedence is the way it is.

History

#1 Updated by Alexey Muranov over 1 year ago

(-1) ** 0.5 should not be defined! I just tried it and it gave me (6.123233995736766e-17+1.0i) -- approximately the complex i. Why not the (-i)??

Well, after some thought, maybe from pragmatic point of view it is better to return i than nothing, but then i would prefer it written clearly as (-1) ** 0.5.

In any case, in mathematics you would put parentheses in (-a)n.

I think that unary +/- have the same precedence as binary, at least in mathematics.

I am -1 for the change.

#2 Updated by Matthew Kerwin over 1 year ago

It woudl never be -i. (-1) ** 0.5 => i (or, in complex coordinates, 0+1i,
which is basically what (6.123233995736766e-17+1.0i) means.

On 11 November 2012 18:01, alexeymuranov (Alexey Muranov) <
redmine@ruby-lang.org> wrote:

Issue #7328 has been updated by alexeymuranov (Alexey Muranov).

(-1) ** 0.5 should not be defined! I just tried it and it gave me

(6.123233995736766e-17+1.0i) -- approximately the complex i. Why not -i ??

Feature #7328: Move ** operator precedence under unary + and -
https://bugs.ruby-lang.org/issues/7328#change-32768

Author: boris_stitnicky (Boris Stitnicky)
Status: Open
Priority: Normal
Assignee:
Category:
Target version:

I would like to ask to consider decreasing ** operator precedence just
below that of -/+ unary operators. I know that other languages (eg. Python)
have ** operator bind tighter than negation, but seeing -1 ** 0.5 give the
result -1 and having to type parenthesis (-1) ** 0.5... Even if it's not
worth changing, I'd like to hear this rationalized. I've asked about
rationalization of this on SO, and nobody seems to know why this precedence
is the way it is.

http://bugs.ruby-lang.org/

--
Matthew Kerwin, B.Sc (CompSci) (Hons)
http://matthew.kerwin.net.au/
ABN: 59-013-727-651

"You'll never find a programming language that frees
you from the burden of clarifying your ideas." - xkcd

#3 Updated by Alexey Muranov over 1 year ago

phluid61 (Matthew Kerwin) wrote:

It woudl never be -i. (-1) ** 0.5 => i (or, in complex coordinates, 0+1i,
which is basically what (6.123233995736766e-17+1.0i) means.

What do you mean? Why (-1)0.5 is i and not -i? Mathematically, it is not defined.

#4 Updated by Alexey Muranov over 1 year ago

I have not still figured out how exactly this mailing issue tracker works, i have not managed to configure it to receive email notifications, and it seems that if i edit my comment, the edited version is not what the others reply to, so i will post again the second part of my comment:

I agree that from pragmatic point of view it may be better for (-1)*0.5 to return i than nothing, but then i would prefer it written clearly as (-1) * 0.5.

In mathematics you would put parentheses in (-a)n. For example: -ex is ... well ... -(ex).

I think that unary +/- have the same precedence as binary, at least in mathematics.

I am -1 for the change.

#5 Updated by Thomas Sawyer over 1 year ago

"In mathematics you would put parentheses in (-a)n. For example: -ex is ... well ... -(ex)."

I think that's the opposite of what's generally expected. Currently Ruby does:

-2**2 #=> -4

but commonly it would be:

-2**2 #=> 4

It's curious how Ruby got the operator precedence it has. Clearly it is based on C, which most languages seem to mimic without much consideration. Yet Ruby stuck ** way up top. I wonder why?

#6 Updated by Alexey Muranov over 1 year ago

trans (Thomas Sawyer) wrote:

"In mathematics you would put parentheses in (-a)n. For example: -ex is ... well ... -(ex)."

I think that's the opposite of what's generally expected. Currently Ruby does:

-2**2 #=> -4

but commonly it would be:

-2**2 #=> 4

It's curious how Ruby got the operator precedence it has. Clearly it is based on C, which most languages seem to mimic without much consideration. Yet Ruby stuck ** way up top. I wonder why?

I am sorry, i hear for the first time that commonly -22 would be 4 :).

Update: i have also never seen in a printed text an expression with parentheses put like in "-(22)".

To the best of my knowledge, in mathematics the exponentiation has the highest precedence, partially maybe because of the way it is written: the base inline, the exponent on top.

#7 Updated by Thomas Sawyer over 1 year ago

@alexeymuranov

-2 * -2 = 4

#8 Updated by Alexey Muranov over 1 year ago

trans (Thomas Sawyer) wrote:

@alexeymuranov

-2 * -2 = 4

This is not the same, and I do not agree with this either. In my opinion, "-2 * -2" is not a legal syntax (the "-" part), it should be (-2)(-2) or -2(-2) = - (2(-2)).

Tomas, can you find a printed or otherwise confirmed example where an expression with parentheses like "-(22)" or "-(ex)" or "-(x2)" is used?

#9 Updated by Thomas Sawyer over 1 year ago

"In my opinion, "-2 * -2" is not a legal syntax (the "-" part), it should be (-2)(-2) or -2(-2) = - (2(-2))."

I don't understand this. Type -2*-2 in Ruby and it produces 4.

"Can you find a printed or otherwise confirmed example where an expression with parentheses like "-(22)" or "-(ex)" or "-(x2)" is used?"

I stand corrected on this. I was thinking in terms of just the numerical value. Sorry.

#10 Updated by Alexey Muranov over 1 year ago

trans (Thomas Sawyer) wrote:

"In my opinion, "-2 * -2" is not a legal syntax (the "-" part), it should be (-2)(-2) or -2(-2) = - (2(-2))."

I don't understand this. Type -2*-2 in Ruby and it produces 4.

I was talking about writing conventions, how i learned them in elementary school. I think it is unfortunate that Ruby allows this "shortcut": if Ruby allows -a * -b, this means that it first computes -a and -b, and afterwards the product. This means that if i want Ruby to compute - a*b in the "standard" way, i have to put the parentheses -(a*b). I consider this a bug.

#11 Updated by Thomas Sawyer over 1 year ago

Actually now that I think about it some more, this is similar to my problem with using power notation in my Stick project (an SI unit system for Ruby). When applying powers to units the result wasn't always the one desired --sometimes you want it to apply to the number, other times to the unit itself (e.g cubic meters). It really would be nice if ^ could be used for power too, along side **, and allow one to be just above unary operations and the other just below. That would provide the most flexibility.

#12 Updated by Thomas Sawyer over 1 year ago

@alexeymuranov Okay, I see what you are saying. But I think the problem really is that mathematical notation tends to be a little too conventional and variant for a programming language, which needs to be more precise. In equations, the negative sign tends to either negate the whole, or is used to mean subtraction. It rarely occurs in the middle somewhere as a negation because it gets factored out to the whole. So it is rarely an issue.

For programming however, it would kind of suck if * -2 was an error b/c * is applied before -. And it could get rather complicated if Ruby tried to apply one order in one case and another order in another.

#13 Updated by Marc-Andre Lafortune over 1 year ago

  • Status changed from Open to Rejected

Quoting Matz from http://www.ruby-forum.com/topic/87126#163398:

People with mathematical background demand precedence for ** being
higher than that of unary minus. That's the reason.

Thomas: Please check your facts, e.g. http://en.wikipedia.org/wiki/Order_of_operations#Exceptions_to_the_standard

#14 Updated by Alexey Muranov over 1 year ago

In mathematical notation, when possible, the "minus operation" is usually introduced as the unary negation, and "a - b" is usually defined as a shorthand notation for "a + (-b)". To avoid any ambiguity, as far as i know (but i do not have a reference), the minus and the plus, both binary and unary, have all the same precedence. To the best of my knowledge, the expression "a * - b" is not a valid syntax in mathematics, at least in languages i am familiar with.

Update: I forgot to say that, having the same precedence, all pluses and minuses, binary or unary, in mathematics are evaluated from left to right (in the absence of parentheses).

trans (Thomas Sawyer) wrote:

@alexeymuranov Okay, I see what you are saying. But I think the problem really is that mathematical notation tends to be a little too conventional and variant for a programming language, which needs to be more precise. In equations, the negative sign tends to either negate the whole, or is used to mean subtraction. It rarely occurs in the middle somewhere as a negation because it gets factored out to the whole. So it is rarely an issue.

For programming however, it would kind of suck if * -2 was an error b/c * is applied before -. And it could get rather complicated if Ruby tried to apply one order in one case and another order in another.

#15 Updated by Thomas Sawyer over 1 year ago

"Thomas: Please check your facts, e.g. http://en.wikipedia.org/wiki/Order_of_operations#Exceptions_to_the_standard"

1) I did not make this issue.
2) If you read #9 you will see that I did check my facts.
3) Some consideration of #11 would at least be nice.

#16 Updated by Marc-Andre Lafortune over 1 year ago

Hi,

trans (Thomas Sawyer) wrote:

"Thomas: Please check your facts, e.g. http://en.wikipedia.org/wiki/Order_of_operations#Exceptions_to_the_standard"

1) I did not make this issue.

My understanding is that the original poster was wondering why the precedence was like that and that he would have preferred it the other way. Alexey answered correctly that the reason was because of the order or operations in mathematics.

I only wanted to suggest that before contradicting someone it was a good idea to check the facts, in particular if one isn't extremely familiar with the field. I didn't mean to offend and I'm sorry if I did.

#17 Updated by Matthew Kerwin over 1 year ago

Can I just point out that everyone is using asterisks and carets and
arguing about standard mathematical notation?

I reckon the biggest factor driving this discussion should be existing
behaviour. Changing how operators behave is probably the single biggest
thing that defines and thus changes a language.

If you were writing a new language, however, I'd find this disussion and
its outcome fascinating.
On Nov 12, 2012 6:37 AM, "marcandre (Marc-Andre Lafortune)" <
ruby-core@marc-andre.ca> wrote:

Issue #7328 has been updated by marcandre (Marc-Andre Lafortune).

Hi,

trans (Thomas Sawyer) wrote:

"Thomas: Please check your facts, e.g.
http://en.wikipedia.org/wiki/Order_of_operations#Exceptions_to_the_standard
"

1) I did not make this issue.

My understanding is that the original poster was wondering why the
precedence was like that and that he would have preferred it the other way.
Alexey answered correctly that the reason was because of the order or
operations in mathematics.

I only wanted to suggest that before contradicting someone it was a good
idea to check the facts, in particular if one isn't extremely familiar with
the field. I didn't mean to offend and I'm sorry if I did.


Feature #7328: Move ** operator precedence under unary + and -
https://bugs.ruby-lang.org/issues/7328#change-32791

Author: boris_stitnicky (Boris Stitnicky)
Status: Rejected
Priority: Normal
Assignee:
Category:
Target version:

I would like to ask to consider decreasing ** operator precedence just
below that of -/+ unary operators. I know that other languages (eg. Python)
have ** operator bind tighter than negation, but seeing -1 ** 0.5 give the
result -1 and having to type parenthesis (-1) ** 0.5... Even if it's not
worth changing, I'd like to hear this rationalized. I've asked about
rationalization of this on SO, and nobody seems to know why this precedence
is the way it is.

http://bugs.ruby-lang.org/

#18 Updated by Boris Stitnicky over 1 year ago

I am pleased by this discussion and I thank Tom Sawyer for showing me that I am not alone who has feelings of surprise at -2 ** 2 behaviour. However, SO people finally found this link (http://www.ruby-forum.com/topic/87126#163398) in which Matz has already rationalized ** behaviour. For this reason, I rescind this feature request (which has already been changed to 'Rejected' status by the time I am writing this), and also for the reasons of stability as per phluid61. Just like Alex Muranov, I do dislike the current result of (-1) ** 0.5, which is (6.123233995736766e-17+1.0i), but that would be another issue, which I don't feel like opening at the moment.

#19 Updated by Alexey Muranov over 1 year ago

Since #7331 is rejected, i do not think anymore it is nonsense to treat unary - specially and give it the highest precedence. Otherwise

  1. it is stuck between * and **
  2. even with respect to ** its behavior does not look consistent to me: the expression -2 ** -2 does not raise an error, but evaluates to (-1/4).

It is not immediately obvious what order of execution to expect from something like -2 * -2 ** -2.

Also available in: Atom PDF