News for hackers. Stuff that matters.
Re:We need to talk about parentheses by boxed on Monday February 12, 2024 @06:24AM (#39343694)
> It depends… on operator precedence

I think implementing operator precedence in ANY programming language is a mistake. `1 + 1 * 2` should be a syntax error. In C, in Python, in Java.

Re:We need to talk about parentheses by lifthrasiir on Monday February 12, 2024 @06:46AM (#39343820)
Some operator precedences are way more reasonable than others, and those between arithmetic operators are good examples. What we actually need is a partial order of operator precedences: you can have `1 * 2 + 3` or `full_name ?? first_name ++ " " ++ last_name` but not necessarily `1 * 2 & 3` because that combination of operators is uncommon and a parenthesis should be preferred instead of an arbitrary total order.
Re:We need to talk about parentheses by zarzavat on Monday February 12, 2024 @07:06AM (#39343921)
Should `x == 1 or y == 3` be a syntax error? Because that’s operator precedence too.
Re:We need to talk about parentheses by kragen on Monday February 12, 2024 @07:22AM (#39344034)
that's certainly a plausible position; in lisp (or = x 1 = y 3) is generally an error; even if it's not an error it doesn't mean what you intend it to. having to write (x == 1) || (y == 3), similar analogous to the code you'd write in lisp, would be only a minor burden

in c, x == 1 || y == 3 works fine, but unfortunately the bitwise operators have the wrong precedence; x & 2 == 2 is parsed as x & (2 == 2), which is never what you meant. so even the best software designers have made terrible blunders in precedence design

math formulas are a bigger issue; 3*x**2 + x/2 + 1 is a lot better than the fully parenthesized version

Re:We need to talk about parentheses by zarzavat on Monday February 12, 2024 @11:38AM (#39346919)
There are of course operations with unclear precedence relationships and it’s completely reasonable to want to force parentheses when composing those operations.

However, there are also operations with crystal clear precedence relationships, such as logical conjunction and comparison, and in that case it has to be asked what exactly would the parentheses be there for?

In lisp the answer is: to enable syntactic homogeneity and to enable macros.

But in other languages like Python that don’t have sexpr based syntax, parenthesizing everything would just be pointlessly unreadable.

Re:We need to talk about parentheses by kragen on Tuesday February 13, 2024 @03:25AM (#39355695)
it isn't crystal clear to everyone, smart guy, it's only clear if you're familiar with it
Re:We need to talk about parentheses by ctrw on Monday February 12, 2024 @07:37AM (#39344126)
That is type inference actually.
Re:We need to talk about parentheses by boxed on Tuesday February 13, 2024 @03:07AM (#39355602)
yea it should
Re:We need to talk about parentheses by sokoloff on Monday February 12, 2024 @06:33AM (#39343748)
There is value in notational simplicity.

For the same reason that math has defined precedence (and even omits multiplication signs entirely in many places), programming languages in some domains will choose to do the same.

It’s not a problem if you want to create a language that does not do this, but I think it is a problem if you want to ban others from doing it.

Re:We need to talk about parentheses by lex-lightning on Monday February 12, 2024 @08:00AM (#39344288)
Yes, but programming is more akin to copywriting than mathematical notation most of the time.

Math has very well-defined, well-trod conventions that are densely packed into the notation. When people try to write code like this though, it’s hard to read.

All else equal, I’ll take a snippet of code with more characters in it but less work to unpack those characters. Reading linearly is cheap; I get tired reading formulas faster than reading technical prose. Precedence makes the mental parsing nonlinear.

Re:We need to talk about parentheses by tsimionescu on Monday February 12, 2024 @07:07AM (#39343928)
Algebra only really has defined precedence between multiplication and addition/subtraction. In all other cases, even division, there is either a non-linear textual representation, or parantheses are required. You have fractions, exponents, radical signs, various signs which appear only at the beginning of an expression (sigma, integral, lim) etc.

Even multiplication is often distinguished more by the shape of the text than by actual precedence rules, once you leave basic arithmetic - expressions like "1 - 3xy + 2y²" make the order of operations obvious from text layout, which is why they are preferred over "1 - 3 × x × y + 2 × y ^ 2", which no mathematician ever writes.

Re:We need to talk about parentheses by sokoloff on Monday February 12, 2024 @07:12AM (#39343961)
Exponentiation also has defined precedence, does it not? (Everyone who has passed algebra agrees that y is squared before being multiplied by 2 in your example.)
Re:We need to talk about parentheses by tsimionescu on Monday February 12, 2024 @07:35AM (#39344102)
You can view that as precedence, but I think it's more correct to say that exponentiation binds to the single symbol it is attached to. When you write x² + 2, I don't think it's operator precedence that makes it clear this is not equal to x ^ 4.

Similarly, in the following expression:

  x
  _ + 2
  2
I don't think it's precedence that makes it clear you first divide by 2 and then add 2 to the result.
Re:We need to talk about parentheses by sokoloff on Monday February 12, 2024 @07:49AM (#39344211)
Alternatively, perhaps what you're observing is simply the graphical representation of the underlying mathematical precedence rules. (Obviously, over hundreds of years of symbolic math, the notation and precedence has co-evolved, with precedence probably generally, well, preceding notation.)

  y = x / 3 + 2

  y = 2 + x / 3

  y = x/3 + 2 
We all agree those are the same, despite a lack of an any cues in the first two. That suggests to me that there is a defined precedence for division vs addition in math. (So much so that it doesn't even seem like a controversial statement to make.)
Re:We need to talk about parentheses by tsimionescu on Monday February 12, 2024 @08:06AM (#39344338)
Precedence rules always apply to a specific textual notation. There is no precedence between division and addition, there is a precedence between the / and the + operators.

People are generally bad at remembering arbitrary operator precedence rules. That is why most math notation doesn't rely on precedence rules to be unambiguous, it uses other kinds of textual clues. For example, the / operator is virtually never used in algebra. Instead, division is indicated by fractions, which explicitly group their operands and separate them from other adjacent operations. Exponentiation relies on super scripts to separate its arguments, making it extremely unambiguous at least which operations are part of the exponent and which the total. Roots use the radical symbol which extends over the entire expression you're taking the root of, and again rely on a kind of superscript for indicating which root you are taking. Limits and sums use subscripts to separate the iteration direction from the expression. Integrals use both sub and superscripts.

Re:We need to talk about parentheses by sokoloff on Monday February 12, 2024 @08:17AM (#39344414)
> Exponentiation relies on super scripts to separate its arguments, making it extremely unambiguous at least which operations are part of the exponent and which the total.

The textual representation even for exponents is not enough if you don't already know that exponentiation has higher precedence than multiplication.

"1 - 3xy + 2xy²"

Both of us know that only the y term is squared in that expression. How do we know that?

I claim that we know that because we know the precedence rules and that someone never exposed to our system of algebra would not inherently and unambiguously know that it was 2·x·(y²) rather than (2·x·y)² or even 2·(x·y)² merely by visual inspection of the expression.

This (the meaning of the above expression, including the precedence/grouping) is something that has to be taught in Alegbra/Prealgebra courses, and is something that some students struggle with.

Re:We need to talk about parentheses by tsimionescu on Monday February 12, 2024 @08:50AM (#39344691)
For expnentiation I was talking about something else:

   1+3
  x    + 4
In this case, the exponent notation makes it unambiguous that this is (x^(1+3))+4, and not x^(1+3+4).

I agree that xy² could mean both (xy)² and x(y²), and that perhaps you need to understand precedence to disbiguate. I would still contend that the notation is defined as "each term has its own exponent, possibly 1 which need not be written" to disambiguate, where terms are separated by parentheses or by other operators.

That is, in my mind, the grammar for usual algebraic notation is something like this:

  expression = term (op term)*
                                                   expression___________ (expression)? 
  term = (num | var | fraction | \( expression \) |        \/expression)

  op = + | - | / | × | ° etc
And the rules are that you first evaluate each term, and then the operators between the terms. You only need to follow precedence rules for those operators between terms, the evaluation of a term is unambiguous.
Re:We need to talk about parentheses by samatman on Monday February 12, 2024 @04:43PM (#39350932)
You appear to be inventing elaborate ways to talk about precedence without saying "precedence".

Precedence, under the term "order of operations", predates computers by several centuries. Which is not to apply that it was fixed in stone from the beginning, or perfectly consistent, but mathematics agreed on the modern rules universally in the first couple decades of the 20th century.

Re:We need to talk about parentheses by thaumasiotes on Monday February 12, 2024 @11:04AM (#39346425)
> Alternatively, perhaps what you're observing is simply the graphical representation of the underlying mathematical precedence rules.

This is nonsense. There are no underlying mathematical precedence rules. You're seeing precedence being represented visually, but there is no mathematical difference between 5 3 ADD 2 MUL and 5 3 2 MUL ADD.

MUL and ADD are just binary operators, or if you prefer, functions from U × U to U for some set U.

Your statement is particularly nonsensical as applied to the example you're supposedly responding to. Given some expressions:

    5 + 3     5           5
   ------- ; --- + 3 ; -------
      2       2         2 + 3
How do you even form the argument that the difference in interpretation is "simply the graphical interpretation of the underlying precedence rules"? The precedence rules here are obvious, because they don't exist:

- Division occurs between the upper operand and the lower operand

- Addition occurs between the left operand and the right operand

It's impossible for these to conflict, so there is no such concept as precedence.

(Precedence also doesn't exist between addition and addition because addition is associative. It is necessary between division and division, and the system is straightforward: lower precedence is indicated by longer lines. Tell me about the underlying mathematical precedence rule that determines that.)

Re:We need to talk about parentheses by sokoloff on Monday February 12, 2024 @11:51AM (#39347121)
> There are no underlying mathematical precedence rules.

You might want to correct the information here then:

https://en.wikipedia.org/wiki/Order_of_operations#Convention...

Re:We need to talk about parentheses by thaumasiotes on Monday February 12, 2024 @01:40PM (#39348585)
What do you think I'd want to correct? That page says the same thing you've already been told twice: there is no underlying mathematics, and the meaning of the notation is defined by the notation. Here's a quote:

> These rules are meaningful only when the usual notation (called infix notation) is used. When functional or Polish notation are used for all operations, the order of operations results from the notation itself.

You could "correct" that to observe that "the order of operations results from the notation itself" is true of all notation, including infix notation, but why? It's not wrong now.

Can you really not tell the difference between "notation" and "math"?

Re:We need to talk about parentheses by samatman on Monday February 12, 2024 @04:47PM (#39350979)
"Order of operations" is the order in which operations proceed. Hence precedence.

They aren't a fact about mathematics. They're a fact about notation. Operator precedence and order of operations are synonymous.

Re:We need to talk about parentheses by dheera on Monday February 12, 2024 @12:44PM (#39347863)
The REAL problem comes from math and physics teachers (even at the university level) writing things like:

(a + b) / 2π

instead of

(a + b) / (2π)

It seems that math teachers put division above multiplication in order of operations but programming languages almost universally treat division and multiplication as equal and read them left-to-right. I've fixed multiple bugs before that were due to this.

Re:We need to talk about parentheses by tempodox on Monday February 12, 2024 @06:28AM (#39343715)
I vigorously disagree.
Re:We need to talk about parentheses by lionkor on Monday February 12, 2024 @06:32AM (#39343739)
For that example, I agree, but how about

    a | b || c >> d & e * f
? I think its reasonable to say that a language should not allow that
Re:We need to talk about parentheses by bmacho on Monday February 12, 2024 @07:18AM (#39344002)
How about *paste Linux source code here*? Should the language C allow it? It's long and complicated, you don't even have enough time to read it, let alone to comprehend it.
Re:We need to talk about parentheses by tempodox on Monday February 12, 2024 @07:15AM (#39343986)
The reason why this expression shouldn't compile has nothing to do with precedences (C has some odd choices here to be sure), but because of mixing incompatible types. Arithmetic integers, bitvector integers, Booleans, and possibly even floats. Conversions to appropriate types should have to be explicit. But C's type system is weak as all hell and this shit actually compiles there. (I'm only mentioning C because your example looks like it.)
Re:We need to talk about parentheses by rfl890 on Monday February 12, 2024 @07:49AM (#39344208)
There‘s no implicit type conversion here. As long as all the vars are the same type it works (albeit unpredictable if you don‘t know operator precedence for the lang).
Re:We need to talk about parentheses by OJFord on Monday February 12, 2024 @06:35AM (#39343758)
You can take any reasonable grammar and come up with unreasonably ugly/illegible code.
Re:We need to talk about parentheses by lionkor on Monday February 12, 2024 @11:00AM (#39346363)
Yeah, of course, but grammar can be designed as to not allow as much implicit magic.

If you can do it, someone will do it (in prod, in your product).

Re:We need to talk about parentheses by samatman on Monday February 12, 2024 @04:52PM (#39351030)
That expression would not pass code review around me, and a linter should flag it for sure.

But all the precedence rules you're invoking here are useful in isolation, and I see no reason why they shouldn't parse in combination. A linter can use heuristics to flag cases which should be parenthesized, a parser would need a defensible rule for failing a parse. What would that rule be?

Re:We need to talk about parentheses by frud on Monday February 12, 2024 @12:06PM (#39347350)
For basically forever compilers and languages have been designed with a total ordering on operator precedences. The Yacc compiler generator tool maps operator precedence to integers, as do most handwritten compiler parsers.

A total ordering has a definite answer to the question "is x greater than, equal to, or less than y?" for all x and y. A partial ordering will answer "I don't know" for some x and y.

It's quite possible to implement operator precedence using a partial ordering. When the parser has to resolve precedence between two operators and their relationship is not defined, throw an "ambiguous precedence" error.

You can implement the partial ordering by putting all the operators into a DAG of sets of operators. If two operators are in the same set, they have equal precedence. If there is a path through the DAG from one operator to the other, that defines the precedence relation. Else there is no relation.

Say "*" is defined to have a higher precedence than "+", and they both have an undefined precedence relation with "&". Then "1 + 2 * 3" should compile into "1 + (2*3)", but "1 + 2 & 3" should throw an "ambiguous precedence" syntax error.

Re:We need to talk about parentheses by adrian_b on Monday February 12, 2024 @01:44PM (#39348641)
The lack of operator precedence has no relationship with the mandatory use of parentheses.

For example the APL syntax for expressions, which I prefer, is that there is no operator precedence.

The operands are associated to operators strictly from the right to the left, regardless which operators or functions are used, which is a much wiser choice than the reverse traditional order of evaluation.

No parentheses are used, except when they are needed to modify the default evaluation order.

Re:We need to talk about parentheses by samatman on Monday February 12, 2024 @04:37PM (#39350861)
That would get really annoying.

Not in expressions like 1 + 3 * 6. Personally, I include the parentheses anyway, as a matter of style, and would write 1 + (3 * 6).

But in expressions like i + 3 > 4 / n? No thank you, (i + 3) > (4 / n) would drive me up a wall. Ymmv.

Re:We need to talk about parentheses by recursivedoubts on Tuesday February 13, 2024 @08:07AM (#39357236)
preach king

https://hyperscript.org doesn’t allow mixing different infix operators w/o parentheses