Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Clarify precedence of numeric literal coefs over parenthesis #21800

Merged
merged 3 commits into from Nov 3, 2017

Conversation

@ronisbr
Copy link
Contributor

commented May 11, 2017

As stated in issue #21798, it was not clear to me that the precedence of numeric literal coefficients with parenthesized expressions is also the same as that of unary operators. This caused confusion with expressions like 6/2(2+1), which results in 1 in julia, but conventionally it should be 9. Hence, the documentation was slightly modified to make this fact much clear.

Clarify precedence of numeric literal coefs over parenthesis
As stated in issue #21798, it was not clear to me that the
precedence of numeric literal coefficients with parenthesized
expressions is also the same as that of unary operators. This
caused confusion with expressions like 6/2(2+1), which results in 1
in julia, but conventionally it should be 9. Hence, the
documentation was slightly modified to make this fact much clear.
!!! warning
Notice that, in this case, the precedence of numeric literal coefficient is
still the same as that of the unary operators. Hence, the expression
`6/2(2+1)` leads to `1` instead of the conventional result `9`, which is

This comment has been minimized.

Copy link
@martinholters

martinholters May 12, 2017

Member

I'm not sure whether 9 is "the conventional result" here. I'm not immediately aware of other programming languages that allow multiplication by juxtaposition. Maybe someone else can chime in here. But in scientific literature, 6/2(2+1) really is somewhat ambiguous - if (6/2)*(2+1) is meant, typically, one would either set 6/2 as a fraction or write this as 6(2+1)/2; if that has not been done, that is somewhat indicative of the intended meaning being 6/(2(2+1)).

I therefore also wonder whether this actually justifies a warning block.

This comment has been minimized.

Copy link
@KristofferC

KristofferC May 12, 2017

Contributor

I must say I agree that this warning is not needed and that the current documentation explains this case clearly already.

This comment has been minimized.

Copy link
@ronisbr

ronisbr May 12, 2017

Author Contributor

@KristofferC,

But, since from a mathematical point of view, it behaves very different from the well established convention, won't you think that more information to make it clear is better?

A simulator we are working was presenting a very strange result and four programmers took one day to figure out what was going on. This happened because the mathematical convention about multiplication and division precedence is very well defined. There is no problem about Julia using a different one for this case, but I think it should be crystal clear to avoid future problems.

This comment has been minimized.

Copy link
@StefanKarpinski

StefanKarpinski May 12, 2017

Member

Let's keep this notation but change it from a warning which sounds a bit too dire to a note.

This comment has been minimized.

Copy link
@vtjnash

vtjnash May 12, 2017

Member

To me, this reads like a direct copy of the previous text in the manual. Perhaps instead it would be better for the text here to give clear guidance on what makes it different, rather than reiterating what it is the same as:

!!! note

The precedence of numeric literal coefficients used for implicit multiplication is higher
than other binary operators such as multiplication (`*`), division (`/`, `\`, and `//`), and exponentiation (`^`).
This means, for example, that `1 / 2im` equals `-0.5im` and `6 // 2(2 + 1)` equals `1 // 1`.

This comment has been minimized.

Copy link
@ronisbr

ronisbr May 12, 2017

Author Contributor

@vtjnash,

Excellent, I really agree with your text. With this note (sorry I did not know that there was a note, that's why I selected warning) it should be crystal clear for everyone that the juxtaposition multiplication sometimes does not behave as the implicit multiplication in mathematics when you have a number before/after a parenthesis. If everyone agrees, then should I create a new PR with the new text and close this one?

This comment has been minimized.

Copy link
@tkelman

tkelman May 12, 2017

Contributor

would be better to update this one in place

This comment has been minimized.

Copy link
@ronisbr

ronisbr May 12, 2017

Author Contributor

Done (I think)!

@ronisbr

This comment has been minimized.

Copy link
Contributor Author

commented May 12, 2017

Hi @martinholters,

In mathematics, when you have only division and multiplication using single line notation, you must always solve the left operation first. For more information:

https://mindyourdecisions.com/blog/2016/08/31/what-is-6÷212-the-correct-answer-explained/

I use the warning because it can lead to wrong calculations. I saw this because I wrote an equation thinking about the usual mathematics convention and Julia was outputting a different value. It took me one day to figure out what was going on.

@martinholters

This comment has been minimized.

Copy link
Member

commented May 12, 2017

The link you posted discusses whether ÷ should always have lower precedence than anything to the right of it. This is not the issue here. The issue is simply whether 6/2(1+2) should be 6/2*(1+2) or 6/(2*(1+2)), i.e. whether juxtaposition has equal precedence as or higher precedence than multiplication with the * operator and division with the / operator, where Julia has chosen the second option, which IMHO is clearly documented.

And as threads like https://math.stackexchange.com/questions/33240/what-is-multiplication-by-juxtaposition show, the "well established convention" you're referring to is not quite that well-established. BTW, my favorite answer there is

So, the question is whether a/bc means (a/b)c or a/(bc). And the answer is, DON'T WRITE a/bc because it will only cause confusion.

Maybe we should add that as a warning. (And this is only half-joking.)

@ronisbr

This comment has been minimized.

Copy link
Contributor Author

commented May 12, 2017

@martinholters,

Let's go back to Math 101 (http://www.purplemath.com/modules/orderops.htm):

In other words, the precedence is:

  1. Parentheses (simplify inside 'em)
  2. Exponents
  3. Multiplication and Division (from left to right)
  4. Addition and Subtraction (from left to right)

The answer for the equation 6/2(2+1) will always be 9. The stackexchange link you posted only improves my point that this must be much more clearly stated in the documentation. Indeed, another user in the same stackexchange link said:

It’s notable that Texas Instruments’ calculators have changed their interpretation from a/(bc)
to (a/b)c, presumably because of the prevalence of expressions like 1/2x where many users intend 1/2 * x.

Julia can really use anything it fits for its purpose, but when it goes against very well-defined convention, then, IMHO, the documentation should say this very loud.

Maybe we should add that as a warning. (And this is only half-joking.)

What is funny about it? Julia is a language for numerical computing. As I said, this behavior deceived four programmers for about one day. I really think we must add a warning to avoid further confusion, because, again, this does not follow the usual mathematical convention.

@andrersimoes

This comment has been minimized.

Copy link

commented May 12, 2017

Hi guys, this sounds a little strange to me too. Sincerelly, a better description in the documentation would be nice, if you don't mind.

The expression itself twists my head. Both results suggested (1 or 9) can easily be extracted there (leads to an ambiguous human interpretation without a clear documentation).

Update text about precedence of numeric literals
The new note about the precedence of numeric literals was updated according to the suggestion of @vtjnash.
@TotalVerb

This comment has been minimized.

Copy link
Contributor

commented May 13, 2017

I have to say that in my mind, 1/2x reads as "one by two ex", not "one half ex". So I don't think this is any universal convention.

@ronisbr

This comment has been minimized.

Copy link
Contributor Author

commented May 13, 2017

@TotalVerb,

Mathematically speaking, multiplication and division has the same precedence and must be solved from left to right. Hence, 1/2x = 1/2*x = 0.5x. This is the convention used in mathematics for those single line equations.

@JaredCrean2

This comment has been minimized.

Copy link
Contributor

commented May 13, 2017

FWIW my TI-89 calculator says 1/2x = x/2 and 6/2(2+1) = 9

@ronisbr

This comment has been minimized.

Copy link
Contributor Author

commented May 13, 2017

That's why I asked to include this note in Julia documentation. It is very easy to make mistakes when you use juxtaposition multiplication. We need to make very clear what will happen when you use it.

@yuyichao
Copy link
Contributor

left a comment

FWIW, I don't agree that 1/2x is unambigueous in math (or at least it is confusing) mainly because I don't think people write things this way.

I agree this should be highlighted in the doc though. It seems that the suggestion at #21800 (comment) is implemented an the current version LGTM.

@TotalVerb
Copy link
Contributor

left a comment

Implicit multiplication does not have higher precedence than exponentiation. This should be fixed before merging.

@ronisbr

This comment has been minimized.

Copy link
Contributor Author

commented May 13, 2017

Hi @TotalVerb,

I think it is. For example:

x = 2
y = 3^2x

In this case, we have y = 81 instead 18, which means that Julia is solving the implicitly multiplication first.

@fredrikekre

This comment has been minimized.

Copy link
Member

commented May 13, 2017

julia> x = 3; 2x^3
54
@ronisbr

This comment has been minimized.

Copy link
Contributor Author

commented May 13, 2017

Hi @yuyichao,

Thanks. I agree that such notation can lead to confusion. Unfortunately, it happens more often than you imagine. See for example this paper:

http://faculty.sdmiramar.edu/faculty/sdccd/hblumenf/rbpaper.pdf

At second paragraph of page 198, we see y = -1/2x meaning y = -1/2*x.

@ronisbr

This comment has been minimized.

Copy link
Contributor Author

commented May 13, 2017

@fredrikekre,

Wow! In your example, it is really computing the exponential first. But in mine, it is computing the multiplication first. I am completely lost now. We need to modify the text. Any ideas? Maybe just remove the exponential part from the note?

@ronisbr

This comment has been minimized.

Copy link
Contributor Author

commented May 13, 2017

I read again and if you just remove the exponentiation than it seems fine. The exponentiation case is handle just before the new part in the documentation.

The precedence of numeric literal coefficients is the same as that of unary operators such as negation. So 2^3x is parsed as 2^(3x), and 2x^3 is parsed as 2*(x^3).

I have already modified the PR.

Thanks!

@yuyichao

This comment has been minimized.

Copy link
Contributor

commented May 13, 2017

we see y = -1/2x meaning y = -1/2*x.

FWIW, that isn't a self consistent example at all. AFAICT it uses cx + dy/ax + by to mean (cx + dy)/(ax + by) on exactly the same page........

@ronisbr

This comment has been minimized.

Copy link
Contributor Author

commented May 13, 2017

Hi @yuyichao !

Yes! This is very confusing. It did not mean to be a consistent example, just to show that people often use this notation and the conventions sometimes are not followed. That's why it is better to say very clear what do you mean about the symbols you write.

@musm

This comment has been minimized.

Copy link
Contributor

commented Jun 16, 2017

is there anything else to do here?

@oscardssmith

This comment has been minimized.

Copy link

commented Jun 16, 2017

I think we should least a warning, and possibly an error if people with this. Alternatively, I think that making Julia parse implicit multiplication as a times symbol with no parens would be reasonable.

@ronisbr

This comment has been minimized.

Copy link
Contributor Author

commented Nov 2, 2017

Guys, is there anything I can do here? Am I missing something?

@martinholters
Copy link
Member

left a comment

I'm fine with the current status.

@StefanKarpinski StefanKarpinski merged commit ae51693 into JuliaLang:master Nov 3, 2017

1 of 2 checks passed

continuous-integration/appveyor/pr AppVeyor build failed
Details
continuous-integration/travis-ci/pr The Travis CI build passed
Details

ararslan added a commit that referenced this pull request Nov 7, 2017

ararslan added a commit that referenced this pull request Nov 14, 2017

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
You can’t perform that action at this time.