News for hackers. Stuff that matters.
Re:Interesting Bugs Caught by ESLint's no-constant-binary-ex... by captbaritone on Wednesday November 08, 2023 @11:34PM (#38201223)
Author of the rule and blog post here. I agree that, for me, I appreciate the extra clarity of explicit parens. This lead me to explore a VSCode plugin which visually show the implicit parens even if they are not present in the code: https://jordaneldredge.com/blog/a-vs-code-extension-to-comba...

I like the idea that different readers of the same code base could opt for differing levels of explicitness when it comes to operator precedence. One thing that working on the project helped demonstrate for me is that adding parens around _every_ subexpression is _way_ too noisy. So, you need to draw the line somewhere. But for me, I prefer drawing that line on the noisier side.

Re:Interesting Bugs Caught by ESLint's no-constant-binary-ex... by kmoser on Thursday November 09, 2023 @03:51AM (#38202590)
> One thing that working on the project helped demonstrate for me is that adding parens around _every_ subexpression is _way_ too noisy. But for me, I prefer drawing that line on the noisier side.

I prefer the noisier side as well. When adding parens to indicate/force precedence, I will sometimes split my expressions into multiple lines, with indentation, as an aid to legibility, e.g. instead of ( ( a + b ) / ( ( c - d ) / e ) ) I might write:

  (
    ( a + b )
      /
    (
      ( c - d )
        /
      e
    )
  )
I've found this not only quite legible, but also fairly easy to edit because you can easily match parens visually.
Re:Interesting Bugs Caught by ESLint's no-constant-binary-ex... by kawhah on Thursday November 09, 2023 @04:29AM (#38202844)
Thanks, I hate it.
Re:Interesting Bugs Caught by ESLint's no-constant-binary-ex... by FlyingAvatar on Thursday November 09, 2023 @06:25AM (#38203659)
I appreciate the attempt, but don't the explicit parens make it pretty clear?

I feel like if you just remove the spaces around the parens themselves, it's the most clear: ((a + b) / ((c - d) / e))

Nowhere I have worked would pass a code review for what you have proposed.

Re:Interesting Bugs Caught by ESLint's no-constant-binary-ex... by innocenat on Thursday November 09, 2023 @07:12AM (#38204006)
If it isn't just a b c d e but longer variable name or function call, then I imagine it wouldn't be as clear.
Re:Interesting Bugs Caught by ESLint's no-constant-binary-ex... by kmoser on Thursday November 09, 2023 @01:22PM (#38208705)
This. An extreme example, where I think my solution works best, is SQL statements that are hundreds of lines long. No sane developer would put that all on one line.
Re:Interesting Bugs Caught by ESLint's no-constant-binary-ex... by FlyingAvatar on Thursday November 09, 2023 @10:02PM (#38214592)
Ahh, I think your example would have communicated the benefit of what you were sharing more clearly with longer variable names. For single word variables, though, it feels needlessly verbose.

To answer your earlier question about object definitions, in cases where the objects are small, I do think more concise (single line) notation can be more readable. An example, though not a great one because it's data more than it's code:

  items: [
    { type: "a", quantity: "12", price: 123.45 },
    { type: "b", quantity: "7", price: 456.78 },
    { type: "c", quantity: "3", price: 9.00 },
  ]
If the number of properties exceeds say 3, or the names of them are complex, I would lean toward the longer form.
Re:Interesting Bugs Caught by ESLint's no-constant-binary-ex... by kmoser on Thursday November 09, 2023 @01:32PM (#38208884)
I'm curious, what is it about my multi-line expression is unclear? I find it easier to match parens when they line up vertically (similar to aligning braces in C functions) than when they're all on one line. True, most IDEs will happily show you a matching paren when you hover over one, but that still doesn't help you understand how a long, one-line expression really breaks down.

Another example: do you write { foo: bar, baz: bat, bing: bang } or:

  {
    foo: bar,
    baz: bat,
    bing: bang
  }
If you use the latter method, why wouldn't you write your expressions the same way? Obviously not the ultra simple ones like a + b, but the longer ones.

Incidentally, I used to write code with no spaces between parens, which is what you suggested: ((a + b) / ((c - d) / e)), but eventually found it much easier to always put spaces around parens: ( ( a + b ) / ( ( c - d ) / e ) ). I would say this is similar to the indent-with-spaces-vs-tabs argument, which will rage forever.

Re:Interesting Bugs Caught by ESLint's no-constant-binary-ex... by rmetzler on Thursday November 09, 2023 @07:16AM (#38204035)
I would rather argue to add temp variables and name parts of the expression, so you can actually understand and communicate what this does.
Re:Interesting Bugs Caught by ESLint's no-constant-binary-ex... by benj111 on Friday November 10, 2023 @03:25AM (#38216469)
Tell me you're a lisp programmer without telling me you're a lisp programmer.

The thing for me is my text editor visually matches the braces, so the second option makes that harder.

Re:Interesting Bugs Caught by ESLint's no-constant-binary-ex... by canucker2016 on Thursday November 09, 2023 @05:55PM (#38212564)
I've written a static code analyzer for C/C++ code. The javascript operator precedence table is almost the same as the C/C++ operator precedence table. So I was pleasantly surprised when I could also run the script on javascript code and have reasonable errors reported as well.

One bug that appeared is bitwise-AND followed by a comparison with no parentheses grouping the bitwise-AND operation. Obviously developers thought the bitwise-AND had higher precedence than the comparison. They were wrong. They obviously didn't test the code either.

Javascript code doesn't twiddle bits as often as C/C++ code so this bug doesn't appear as often.

For text editor support of this problem, what may work is to show that an expression with higher precedence IS evaluated first before the expression using an operator lower on the operator precedence table.

There was a suggestion in the Vim mailing list years ago to use background color to show the nesting depth of a block.

One could use background color or a font attribute, say underline or font-size, to indicate the evaluation order of a non-parenthesized multi-operator expression.

HN posts only support italics for font formatting so I'll use that in my example - hmmm, looks like I can't use block formatting in addition - just imagine the code indented in a fixed-width font

====

if (x & 3 == 1) { // do something }

===