Julia: Shouldn't `โˆš3x` parse as `โˆš3 * x`? It doesn't.

Created on 18 Jun 2018  ยท  13Comments  ยท  Source: JuliaLang/julia

I would argue that juxtaposition of constants and variables, such as 3x should be generalized to work with literals such as โˆš3, so that โˆš3x parses as (โˆš3) * x instead of the current โˆš(3x). It might be me, but the current parsing is very surprising, specially with longer variable names, 2variable1 + โˆš3variable2. A bug in a pattern like this had me staring at a single line of code for ~10 minutes, before I figured what was wrong!

Without "vincula", such as in โˆš3ฬ…xฬ…, this is obviously ambiguous, but I think that the current parsing is actually inconsistent with the parsing of 3x^2, which correctly parses according to the standard math convention, first the power, then the multiplication.

A suggestion in slack by Chris Peel was to change the parsing and additionally teach the parser to understand \sqrt{3x}, so that we can still have the present behaviour, but with a vincula rendered using unicode. That part might be much more tricky, however.

parser

Most helpful comment

This is because both โˆš and literal multiplication parse like unary operators, and unary operators are right-associative. I guess the proposal here is to give implicit multiplication strictly lower precedence than unary operators.

If you're willing to write \sqrt{3x} you might as well write โˆš(3x).

All 13 comments

Can we get this issue a bug tag and priority? I am not sold on the vincula stuff, but definitely should be parsing it according to the rules of operations.

This is because both โˆš and literal multiplication parse like unary operators, and unary operators are right-associative. I guess the proposal here is to give implicit multiplication strictly lower precedence than unary operators.

If you're willing to write \sqrt{3x} you might as well write โˆš(3x).

I think the current parsing is intended, and it is also thoroughly documented in its own manual section: https://docs.julialang.org/en/latest/manual/integers-and-floating-point-numbers/#man-numeric-literal-coefficients-1

It is a little strange though โ€” numeric juxtaposition already behaves like it's lower precedence for two of the other unary operators (+ and -) because those are parsed as part of the number instead of as an operator.

I think the manual is a little vague about the combination of unary operation and implicit multiplication,. I believe it just says that "The precedence of numeric literal coefficients is the same as that of unary operators". To me that seems at odds with the parsing of โˆš in โˆš3x at a lower precedence than 3x. The real reason is right-associativity, as @JeffBezanson clarified.

In any case, was there a strong argument behind the current choice of precedence? Would the proposed change, as stated by @JeffBezanson, produce any unwanted side effect? And if not, am I alone in thinking that this change would make silent bugs less likely?

Upon further thought, I think the deeper issue here for me is the implicit assumption that juxtaposition should be perfectly equivalent to spelling out the multiplication. It might be my years using Mathematica (where โˆš3 x == โˆš3 * x == (โˆš3) x and 2^3x == 2^3*x == (2^3)x, both unlike Julia), but I think it is a very natural assumption to make at first glance.

I would therefore not propose to change the precedence of unary operators relative to juxtaposition, but rather parse juxtaposition literally as *. Would that make sense?

This is not a bug, it's a matter of taste. Mathematica does something else, which is fine; Julia's rules are designed to match intuitive mathematical notation. No matter what rules you pick some people are going to be unhappy some of the time. We've been using these rules for a long time at this point with minimal issues and now is really not the time to change them.

Perhaps the documentation could include an example such as the case at hand to indicate that it can parse differently from the mathematical operators order of precedence? I thought 3x would just re-write/expand it to long from 3 * x, but it isn't the case. It is documented, so I agree it is a more of a design issue and not a bug.

Something like: 3x parses to (3 * x) and not 3 * x.

That's not even it, however, as 3x^2 is not (3 * x)^2. Anyway, I think I'll close this for the moment. It is indeed probably a matter of getting used to Julia's rules.

^ has asymmetric precedence: -x^2 is -(x^2) but x^-2 is x^(-2). But I believe that's mostly unrelated to this issue, which is about the relative precedence of implicit multiplication and other unary operators.

I think @mbauman has a good point: -3x is parsed as -3 * x, so changing this could be seen as more consistent (although this is indeed parsed as a literal -3 and not as a call to -).

I would therefore not propose to change the precedence of unary operators relative to juxtaposition, but rather parse juxtaposition literally as *. Would that make sense?

Would that mean that 3 / 2x would then parse as (3/2)*x instead of 3/(2*x)? Using juxtaposition behind a division operator to avoid parens, is one of my favorite use cases.

I don't think so, if we just change the parsing of unary operators, such as โˆš, as I understand is suggested by @JeffBezanson. We would just have to make โˆš tighter, much like unary -, so it operates with higher precedence than juxtaposition.

Fun fact: the Android calculator on my phone says โˆš3ฯ€ is 5.441..., i.e. (โˆš3) * ฯ€

EDIT: I think I was not clear. I understand my updated proposal to parse juxtaposition as * is probably too disruptive at this stage. However, a change restricted to the behaviour of โˆš would perhaps be desirable and acceptable, it would make parsing more consistent (with - in particular) and would solve my issue here completely.

I will try giving juxtaposition slightly lower precedence than unary operators and see how it goes.

Was this page helpful?
0 / 5 - 0 ratings