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
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.
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:
" 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)
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.
It makes sense for expressions like
1/2x
where it matches the intuition, cf.
1/2x
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.
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).
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].)
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.
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.
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.
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.
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)
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
))))