Hacker News new | past | comments | ask | show | jobs | submit login

Sorry, but I'm of the exact opposite opinion. If you don't know, learn. It's not hard (as other sibling comments have noted). Code with superfluous parentheses is even more confusing, since I expect them to be present only when overriding precedence.

...and I just realised your username adds some additional irony.




Explicit is better than implicit. I think the real problem is not breaking up complicated expressions. If it's more than just a few pairs of parentheses making it hard to read there's something more wrong there.


I think most people agree "a*x**b + c" is more clear than "(a*(x**b))+c". Or "a+b+c+d" is more clear than "a+(b+(c+d))".

Why are we happy to avoid parentheses for these operations but not for && and ||? Probably because we are all really used to the precedences for + and *.

So at the end of the day, what's more clear depends on How familiar the engineers working on your code are with a given set of operators.


Parentheses need to be matched. That adds cognitive overhead. It's especially frustrating when you find the closing parenthesis and then realise it wasn't even necessary.

IMHO it's on a similar level as "== true" "== false" and variations thereof --- absolutely redundant and unnecessary, and shows a lack of knowledge. The same "explicit is better than implicit" mantra is often repeated to justify the latter, but if you think

    if(x == true)
is somehow more "explicit", then surely

    if((x == true) == true)
is even better?

So at the end of the day, what's more clear depends on How familiar the engineers working on your code are with a given set of operators

If someone is not familiar then they should be encouraged to learn and level up, rather than pulling down everyone else.


I got little scars from knowing precedences and then switching languages. I also got them from short-testing booleans that later turned into T|boolean. And all these clean just_p’s incrementally evolved into !just_p ? !un_q : t’s. Because I was flying through a mass-change after a day and had no mental capacity to repack the meaning of the previous expression and retain the context of a changeset.

Crystallized syntax is clear, but also extremely fragile, if you take humans into account. We have limits. Everything pushes us to these limits. Any complexity spike that overlaps with secondary complexity or fatigue is above our limits. That’s where we make mistakes.


The big difference between adding the first `== true` to `if (x)` and adding more is that for a bare `x` you need more context to know whether the expression inside the `if` is of boolean type or something that will implicitly be casted to boolean. With `x == true` you know just looking at the `if` statement that it is a boolean expression. Adding more `== true` does not make it more explicit.


Just nitpicking: "a+b+c+d" in C is equivalent to "((a+b)+c)+d" not to "a+(b+(c+d))".

I otherwise agree with your comment: in most cases, unnecessary parentheses make the code slower to read, just like unnecessary "==true".


just a fun little anecdote.

I wrote a piece of code that said ` if ( boolean_variable == true)`

this was meant to be "if neither false nor null", since the variable was nullable (kotlin), until someone else tried to "fix the beginner mistake" :P

luckily kotlin requires you handle the nullability and the other person immediately figured out what was going on.

The other person was me, a couple of months down the line.


If the purpose of quirky code isn't immediately clear from the context (and if the code can't easily be reworked to make it cleaner), it's a good candidate for commenting.


Most people might agree with that, I don't know, but I know I don't think your first example is clearer. And I've had the operator precedence rules memorized for decades. Parentheses save my brain a step.

The second example is irrelevant because addition is commutative so the parentheses are meaningless. (This is why languages shouldn't override + to be a concatenation operator.)


The important part that makes the parens in the second operation unnecessary is that addition is associative, not that it's commutative. And concatentation is also associative, so even if those were strings, the parens would still be unnecessary.

That is, (a+b)+c == a+(b+c).

Interestingly, C integer addition is not actually associative, since (1+INT_MAX) + (-1) is UB, but 1+(INT_MAX+(-1)) should in principle be defined as INT_MAX.


And floating-point addition is not associative in any language:


I think the opposite, I think most people would prefer the version with parentheses, including myself, also, in 20 years experience all companies I’ve worked for would prefer the second expression.

The first expression looks messy and confusing, the second is completely clear in how it will work.


If you drag it out of context, sure the first example looks more clear. But there is a difference between Boolean logic and arithmetic, and as soon as you use proper variable names, that becomes evident:

(isAdmin || (canReadDocument && canModifyMetadata)) && accountIsActive

Using parentheses makes the code a lot easier to understand here. All these variables carry state with lots of subtleties. Figuring out the implications of all the different cases becomes a lot easier when the code clearly tells them apart.


    ((x**b) * a) + c
Is equivalent and is the clearer way to express it.


Although I agree, most times where I mix any of these without parentheses I end up having to explain it either in code review or when somebody does a `git blame` a couple months later. Rather than waste everyone's time explaining it, it's easier to just use the parentheses since it's what many/most people expect and everyone else can read it well enough.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: