...and I just realised your username adds some additional irony.
...and I just realised your username adds some additional irony.
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.
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.)
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.
((x**b) * a) + c
Is equivalent and is the clearer way to express it.The first expression looks messy and confusing, the second is completely clear in how it will work.
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.
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.
(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.
I otherwise agree with your comment: in most cases, unnecessary parentheses make the code slower to read, just like unnecessary "==true".
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.