A puzzling result with a simple calculation

Hi,

is this an anomaly?

julia> 6/2(2+1)
1.0

against, with an explicit times operator:

julia> 6/2*(2+1)
9.0

(this was prompted by a video on Dave Cutler’s channel).

Using Julia 1.10.3.

Graham

I would call this a bug.

From the manual:

Numeric literal coefficients, e.g. 2x, are treated as multiplications with higher precedence than any other binary operation, with the exception of ^ where they have higher precedence only as the exponent.

See also the section on numeric literal coefficients:

https://docs.julialang.org/en/v1/manual/integers-and-floating-point-numbers/#man-numeric-literal-coefficients

10 Likes

" Numeric literal coefficients, e.g. 2x, are treated as multiplications with higher precedence than any other binary operation, with the exception of ^ where they have higher precedence only as the exponent."

https://docs.julialang.org/en/v1/manual/mathematical-operations/

2(2+1) is treated as 2(3)

1 Like

I get it that it’s not an implementation error, but is this not a bit weird and counter-intuitive? What’s the thinking here?

I’m not a huge fan of juxtaposition myself, but it enables things like

julia> 1 / 2pi
0.15915494309189535

which some people find neat.

3 Likes

It makes sense for expressions like

1/2x

where it matches the intuition, cf.

1/2x

7 Likes

Yes, we are used to that sort of notation. But I have already faced confusion by mathematicians when showed them the Boltzmann equation e^{-E/kT}, and they readily interpreted that as e^{-(E/k)\times T}. It might seem intuitive, but formally I think it is wrong. I would prefer not to have that ambiguity.

5 Likes

It’s a choice for which there’s no clear or definitive answer — perfect fodder for limitless internet discourse and gathering comments for “engagement” metrics.

The previous time this made the rounds, it was 8/2(2+2): Poorly constructed math equation prompts Twitter debate – can you solve it? – New York Daily News (or this wayback archive to avoid the paywall).

12 Likes

I do like the juxtaposition notation, but for a programming language it might have been better to avoid the ambiguity since it can lead to bugs.

(I mean, it’s not ambiguous to the parser, it’s ambiguous to human readers and programmers [unless they study the precedence rules].)

1 Like

It really helps legibility in complicated expressions, and I don’t understand how there’s any ambiguity.

There’s a world of difference between reading lots of 2x and lots of (2 * x), which is the alternative.

This is a matter for coding standards or style guides. Don’t take this away.

4 Likes

It’s obviously not going away since that would be a breaking change.

There’s ambiguity because folks are used to the usual precedence rules for arithmetic operators in other programming languages. At the end of the day, Julia is not math, it’s a programming language.

But anyways, like I said, I like juxtaposition, but we have to acknowledge the downside.

Any infix notation requires (implicit) knowledge of precedence rules and associativity to resolve ambiguities when parsing. The juxtaposition notation is not better or worse, but just less conventional.
(Lisp syntax is unambiguous, but less popular as a notation)

As a theoretical physicist I have to say that I like this way of writing and reading math in code. Parentheses really obfuscate the math in imho. But indeed this splits the waters and I doubt there is a correct approach. Luckily in julia we get to decide as it’s by no means enforced. :blush:

3 Likes

This is exactly what I meant. Because it’s less conventional, programmers are more likely to make mistakes that lead to bugs.

Sure, but there is always a choice/convention involved: While 1:end-1 is nice, I regularly forget that 1 .+ 1:10 does not work as intended … in the end, I decided to use 1:(end-1) and 1 .+ (1:10) just to be sure.

1 Like

True, but at the price of confusing examples like the one in the OP

This: 2(2+1) is actually function call syntax, but applied to a literal number. It wouldn’t be inconsistent, imo, to prohibit this, but allow 2x. After all, 22 isn’t parsed as 2*2.

But anyway, I don’t see a large risk of misunderstanding. If you see 1/2(2+1), you either already know what it means, or you are completely baffled, and need to look it up.

1 Like

Note that under Physical Review rules, when writing fractions with a slash, multiplication has higher precedence than division. That is, implicit multiplication. So this rule has been formalized to some extent, and even mathematicians will read 2x/2x as 1, not x^2.
(p. 20, https://cdn.journals.aps.org/files/styleguide-pr.pdf)

7 Likes

I think for a number literal, juxtaposition is multiplication syntax not function-call syntax.

julia> Meta.@lower 2(2+1)
:($(Expr(:thunk, CodeInfo(
    @ none within `top-level scope`
1 ─ %1 = 2 + 1
│   %2 = 2 * %1
└──      return %2
))))
1 Like