Let's say I have a boolean condition a AND b OR c AND d and I'm using a language where AND has a higher order of operation precedent than OR. I could write this line of code:

If (a AND b) OR (c AND d) Then ...

But really, that's equivalent to:

If a AND b OR c AND d Then ...

Are there any arguments in for or against including the extraneous parentheses? Does practical experience suggest that it is worth including them for readability? Or is it a sign that a developer needs to really sit down and become confident in the basics of their language?

I may be lazy, but I prefer to have parentheses in most of such situations for readability.
–
thorsten müllerJun 11 '13 at 14:16

3

Me too. I'm just hoping I'm doing it more for readability and less because I'm too lazy to become confident/competent in the basics of my langauge.
–
Jeff BridgmanJun 11 '13 at 14:31

10

Good usage of parentheses is like good usage of grammar. 2 * 3 + 2 might be the same as (2 * 3) + 2 but the second is easier to read.
–
Mathew FoscariniJun 11 '13 at 14:36

9

@Mathew Maybe if you’re weak in maths. For more complex cases, sure, use parentheses. But for blindingly obvious ones (BODMAS …) they reduce readability more than aiding it due to clutter.
–
Konrad RudolphJun 11 '13 at 21:40

15 Answers
15

Good developers strive to write code that is clear and correct. Parentheses in conditionals, even if they are not strictly required, help with both.

As for clarity, think of parentheses like comments in code: they aren't strictly necessary, and in theory a competent developer should be able to figure out code without them. And yet, these cues are exceedingly helpful, because:

They reduce the work required to understand the code.

They provide confirmation of the developer's intent.

Furthermore, extra parentheses, just like indentations, whitespace, and other style standards, help visually organize the code in a logical way.

As for correctness, conditions without parentheses are a recipe for silly mistakes. When they happen, they can be bugs that are hard to find--because often an incorrect condition will behave correctly most of the time, and only occasionally fail.

And even if you get it right, the next person to work on your code may not, either adding errors to the expression or misunderstanding your logic and thus adding errors elsewhere (as LarsH rightly points out).

I always use parentheses for expressions that combine and and or (and also for arithmetic operations with similar precedence issues).

Although, I've heard it said comments are apologies (for bad/hard-to-read code)... there's a good chance you could have written it better. I guess you could say a similar things about parentheses.
–
Jeff BridgmanJun 11 '13 at 21:05

5

Another aspect of correctness is preserving it through changes: While the original developer may get precedence right without parentheses when he first writes the code with the purpose and context fresh in mind, he (or another) who comes along later and doesn't remember all the details may well mess it up when they add more terms to the expression. (That was mostly implied already but I felt like it was worth emphasizing.)
–
LarsHJun 12 '13 at 13:33

1

@LarsH, thanks, I added this explicitly to the answer.
–
dan1111Jun 12 '13 at 13:36

3

+1 "They provide confirmation of the developer's intent." - any programmer (OK, maybe not all, but all of those that reside here....) can work out what the compiler will do with the most complex logic. Absolutely no one can work out what the original developer intended (Including himself) a few weeks down the track for anything beyond the simplest.....
–
mattnzJun 14 '13 at 3:24

1

I think @JeffBridgman was referencing a fairly well known standpoint of "comments can sometimes be a code smell". E.g. see Jeff Atwood's summary which includes the question "Can you refactor the code so the comments aren't required?". I'd argue that if your comment is explaining why your code is so damn un-intuitive, it can definitely be a hint that something's wrong. At times like this, it's a good idea to simplify the code. I completely agree with your actual answer though and take on parentheses, however.
–
Daniel BJun 14 '13 at 11:18

It matters less if you are confident in your grasp of the language. What matters is the grasp of the language of the n00b that follows you.

Write your code in the clearest most unambiguous way possible. Extra parenthesis often (but not always) help. Putting only one statement on a line often helps. Consistency in coding style often helps.

There is such a thing as too many parenthesis, but it's one of those situations where you won't need advice - you'll know it when you see it. At that point refactor your code to reduce the complexity of the statement rather than remove parenthesis.

Don't forget that even if you're a solo developer when ill, tired, or dealing with code you wrote last year; your comprehension level is reduced to that of a n00b.
–
Dan NeelyJun 11 '13 at 16:01

24

There is such a thing as too many parenthesis -- you're obviously not a lisper ;)
–
paulJun 11 '13 at 17:12

13

That’s bad advice: Do not write for noobs. This will reduce your code quality (considerably) because you cannot use well-established idioms that go beyond the first two chapters of a beginner’s book.
–
Konrad RudolphJun 11 '13 at 21:41

10

@KonradRudolph: maybe so, but don't write for the only guys who know the Art of Computer Programming from cover to cover either, or be prepared to have to debug their code afterwards, and not have a clue why you did things that way. Code is read a lot more than it's written.
–
haylemJun 11 '13 at 23:20

14

@dodgethesteamroller: I've seen far too many competent/respected developers introduce precedence bugs (everyone has a bad day now and then) that remain unnoticed for ages. For good developers who do know the precedence rules, the risk of undetected mistakes/typos is too high. For everyone else the risk is higher. The best developers are the developers that used to remember the language's precedence rules, but forgot them due to habitually using parenthesis for anything non-obvious.
–
BrendanJun 12 '13 at 5:09

Yes

You should always use parens... you do not control the order of precedence... the developer of the compiler does. Here is a story that happened to me about non use of parens. This affected hundreds of people over a two week period.

Real World Reason

I inherrited a main-frame application. One day, out of the clear blue it stopped working. That's it... poof it just stopped.

My job was to get it working as fast as possible. The source code had not been modified for two years, but all of the sudden it just stopped. I tried to compile the code and it broke on line XX. I looked at line XX and I could not tell what would make line XX break. I asked for the detailed specs for this application and there were none. Line XX was not the culprit.

I printed out the code and started reviewing it from the top down. I started to create a flowchart of what was going on. The code was so convoluted I could hardly even make sense of it. I gave up trying to flowchart it. I was afraid to make changes without knowing how that change would effect the rest of the process, especially since I had no details of what the application did or where it was in the dependency chain.

So, I decided to start at the top of the source code and add whitespce and line brakes to make the code more readable. I noticed, in some cases, there were if conditions that combined ANDs and ORs and it wasn't clearly distinguishable between what data was being ANDed and what data was being ORed. So i started putting parenthesis around the AND and OR conditions to make them more readable.

As I slowly moved down cleaning it up, I would periodically save my work. At one point I tried compiling the code and a strange thing happend. The error had jumped passed the original line of code and was now further down. So I continued, speparating the AND and OR conditions with parens. When I got done cleaning it up it worked. Go Figure.

I then decided to visit the operations shop and ask them if they had recently installed any new components on the main-frame. They said yes, we recently upgraded the compiler. Hmmmm.

It turns out that the old compiler evaluated expression from left to right regardless. The new version of the compiler also evaluated expressions from left to right but ambiguous code, meaning unclear combination of ANDs and ORs could not be resolved.

Lesson I learned from this... ALWAYS, ALWAYS, ALWAYS use parens to separated AND conditions and OR conditions when they are used in conjuction with each other.

I couldn't rewrite it because there were no specs. The original author was long gone. I remember intense pressure. An entire cargo ship was stranded in port and could not be off loaded because this little program did not work. No warning. No changes to the source code. It only dawned on me to ask the Network Operations if they modified anything after I noticed that adding parens shifted the errors.

That seems like a better illustration of why it's important to have a good compiler.
–
ruakhJun 11 '13 at 19:35

2

@CapeCodGunny: I'm sure you didn't. But the problem here is that you had a bad compiler vendor that made a breaking change. I don't see how you learned a lesson to "ALWAYS, ALWAYS, ALWAYS" work around that problem, even when using better compilers.
–
ruakhJun 11 '13 at 20:55

3

@ruakh - No, the vendor simply changed their code parser. I'm old school, I don't rely on my ability to remember every system I've coded or been involved in. Without documentation all you have is the source code. When the source code is difficult to read and follow it creates an extremely stressful situation. Programmers who don't use whitespace have probably never had to deal with a situation like the one I was faced with. I also learned that it makes more sense to write code like: See Dick; See Jane; See Dick AND Jane; Simple statements that are easy to read... comment out... and follow.
–
Cape Cod GunnyJun 11 '13 at 22:06

5

I think there are lessons learned here on both sides... You're much better off using parentheses especially when the alternative is relying on the undocumented behavior of a compiler in regard to ambiguous code. And if the programmer doesn't know which expressions are ambiguous, better use parens. On the other side, it's dangerous to change the behavior of a compiler, but at least it threw an error in cases where behavior changed. It would have been worse if the compiler had not thrown an error, but had begun compiling differently. The error protected you from unnoticed bugs.
–
LarsHJun 12 '13 at 13:38

1

@Kaz: Because of experience. Parenthesis is more reliable than using the precedence and (using well) transmit my intention much better. And yet, many times I decompose long boolean sentences on boolean variables (where available, when not I do the most common idiom to emulate them) much before introduce local refactoring became common on IDEs.
–
Fabricio AraujoJun 13 '13 at 18:48

Well said, though I think "May result in cluttered, difficult to read code" is rather subjective.
–
FrustratedWithFormsDesignerJun 11 '13 at 14:42

1

How does making the semantics of your code explicit make it difficult to read?
–
Mason WheelerJun 11 '13 at 14:44

1

I agree with the others in questioning your "Yes Cons". I think it is almost always the opposite.
–
dan1111Jun 11 '13 at 14:56

@Frustrated As subjective as the opposite claim. Meaning, not at all, really. Just hard to measure.
–
Konrad RudolphJun 11 '13 at 21:40

1

@MasonWheeler: While I agree that explicit parens are very important in many cases, I can see how one can go overboard on making semantics explicit. I find 3 * a^2 + 2 * b^2 easier to read than (3 * (a^2)) + (2 * (b^2)), because the format and precedence is familiar and standard. Likewise, you could (to be extreme) forbid the use of functions and macros (or compilers!) in order to make the semantics of your code more explicit. Obviously I'm not advocating that, but I'm hoping to answer your question as to why there need to be limitations (a balance) on making things explicit.
–
LarsHJun 12 '13 at 13:45

The parentheses are semantically redundant, so the compiler doesn't care, but that's a red herring--the real concern is programmer readability and comprehension.

I'm going to take the radical position here and give a hearty "no" to the parentheses in a AND b OR c AND d. Every programmer should know by heart that precedence in Boolean expressions goes NOT > AND > OR, just like remembering Please Excuse My Dear Aunt Sally for algebraic expressions. Redundant punctuation just adds visual clutter most of the time in code with no benefit in programmer readability.

Also, if you always use parentheses in logical and algebraic expressions, then you give up the ability to use them as a marker for "something tricky is happening here--look out!" That is, in the cases where you want to override default precedence and have addition evaluated before multiplication, or OR before AND, parentheses are a nice red flag to the next programmer. Too much use of them when they're not needed, and you become the Boy Who Cried Wolf.

I would make an exception for anything outside the realm of algebra (Boolean or not), such as pointer expressions in C, where anything more complicated than standard idioms like *p++ or p = p->next probably ought to be parenthesized to keep the dereferencing and the arithmetic straight. And, of course none of this applies to languages like Lisp, Forth, or Smalltalk that use some form of Polish notation for expressions; but for the majority of mainstream languages, logical and arithmetic precedence are totally standardized.

+1, parentheses for clarity are fine, but AND vs OR is a fairly basic case which I would want the other devs on my team to know. I worry that sometimes "using parentheses for clarity" is really "using parentheses so I never have to bother to learn the precedence".
–
Tim GoodmanJun 12 '13 at 13:40

In all the languages I work with regularly it's .member before unary operators, unary before binary operators, * and / before + and - before < and > and == before && before || before assignment. Those rules are easy to remember because they match my "common sense" about how the operators are normally used (e.g., you wouldn't give == greater precedence than + or 1 + 1 == 2 stops working), and they cover 95% of the precedence questions I'd have.
–
Tim GoodmanJun 12 '13 at 13:48

1

@TimGoodman Yes, exactly right, to both your comments. Other responders here seem to think it's a black or white question--either use parentheses all the time, no exceptions, or fly carelessly by the seat of your pants through a sea of arbitrary and impossible-to-remember rules, your code boiling over with potential hard-to-spot bugs. (Mixed metaphors very intentional.) Obviously the right way is moderation; code clarity is important, but so is knowing your tools well, and you should be able to expect a certain minimum understanding of programming and CS principles from your teammates.
–
dodgethesteamrollerJun 12 '13 at 19:57

Are there any arguments in for or against including the extraneous parentheses? Does practical experience suggest that it is worth including them for readability? Or is it a sign that a developer needs to really sit down and become confident in the basics of their language?

If no one else ever would have to look at my code again, I do not think I would care.

But, from my experience:

I look at my code again occasionally (sometimes years after writing it)

Others sometimes look at my code

Or even have to expand/fix it!

Neither myself or the other remembers exactly what I was thinking when writing it

Writing cryptic "minize the character count" code hurts readability

I almost always do this because I trust my ability to quickly read and not make little mistakes a lot more with parens than nothing else.

In your case, I would almost assuredly do something like:

if (a AND b) then ab = true
if (c AND d) then cd = true
If (ab OR cd) Then ...

Yes, it's more code. Yes, I can do fancy bool operators instead. No, I don't like the chance when skimming code 1+ years in the future I misread fancy bool operators. What if I was writing code in a language which had different AND/OR precedence and had to jump back to fix this? Am I going to go, "aha! I remember this clever little thing which I did! I didn't have to include parens when I wrote this last year, good thing I remember now!" if that happens (or worse, someone else who wasn't aware of this cleverness or was thrown into a "fix asap" type situation)?

Separating with () makes it so much more straightforward to quickly skim and understand later...

General case

In C#, multiplication and division has a precedence over addition and subtraction.

Still, StyleCop, a tool which enforces common style across the codebase with an additional goal to mitigate the risk of bugs introducing by code which may not be clear enough, has the rule SA1407. This rule will produce a warning with a piece of code like this:

var a = 1 + 2 * 3;

It's clear that the result is 7 and not 9, but still, StyleCop suggests to put parenthesis:

var a = 1 + (2 * 3);

Your particular case

In your particular case, there is a precedence of AND compared to OR in the particular language you use.

This is not how every language behave. Many others treat AND and OR equally.

As a developer who works mostly with C#, when I saw your question the first time and read the piece of code without reading what you've wrote before, my first temptation was to comment that the two expressions are not the same. Hopefully, I've read the whole question entirely before commenting.

This particularity and the risk that some developers may believe that AND and OR have the same priority makes it even more important to add parenthesis.

Don't write code with a goal to show that you're smart. Write code with a goal of readability, including by people who may not be familiar with every aspect of the language.

Re: "Every language I know treat AND and OR equally": I doubt that's true. If it is true, then you don't know any of the ten most popular languages (C, Java, C++, PHP, JavaScript, Python, C#, Perl, SQL, and Ruby), and are in no position to be commenting on what is "uncommon", let alone "very uncommon".
–
ruakhJun 11 '13 at 19:34

1

@ruakh: thank you for your comment. Indeed, I haven't thought enough about different languages. I edited the answer.
–
MainMaJun 11 '13 at 19:44

1

Languages in which AND and OR are binary operators, and which do not treat AND as having a higher precedence than OR, are braindamaged crap whose authors are computer science flunkies. This comes from logic notation. Hello, does "sum of products" not mean anything? There is even a boolean notation which uses multiplication (juxtaposition of factors) for AND, and the + symbol for OR.
–
KazJun 12 '13 at 7:53

1

@ruakh You just made my point for me. Because there are a handful of pathological edge cases doesn't mean that you shouldn't learn standard Boolean precedence and assume it holds until proven otherwise. We're not talking about arbitrary design decisions here; Boolean algebra was invented long before computers. Also, show me the Pascal spec you're talking about. Here and here show AND before OR.
–
dodgethesteamrollerJun 12 '13 at 19:51

Yes. Ideally, logical expressions should be in either Disjunctive Normal Form or Conjunctive Normal Form with parenthesis. Primarily because not everyone is familiar with the order of precedence regarding OR and AND, and it's easier to read this:

I will use parenthesis even if it is optional, why because it helps to better understand for everyone, for the one who write the code as well as the one ready to see that code. In your case even the boolean operators have precedence it might work well at first, but we can't say it will help you in every case. so i prefer to user parenthesis in any condition that it may require it or optionally.

Basically, a conditional is still just an algebraic expression, and by clearly using parenthesis, you can more easily apply the various algebraic rules you already know to the expression, including ye olde concept of "simplify or expand this formula".

I'm not sure you're actually answering the question, since you lead your answer with an assumption that isn't necessarily true. Would I use parentheses for algebra? Not all the time. If it helps with readability, then certainly, but others have already expressed that here. And expanding mathematic algebra into other forms doesn't exactly have a one-to-one correspondence to programming - what if you are checking the status of a few string values?
–
DerekJun 11 '13 at 19:46

If the corresponding boolean algebra is complicated enough to warrant parens, your conditional should probably use parens. If it's simple enough not to warrant parens, you either don't have to, or shouldn't. Either way, thinking of it as you would a mathematical expression probably clarifies the issue.
–
NarfanatorJun 11 '13 at 20:09

My examples above use two and four booleans. If you're checking the status of two or more string values, it maps. Each check corresponds to one boolean variable; regardless of whether that check is integer or string equality; string, array or hash inclusion; a complex expression itself... Doesn't matter; all that matters is you've got more than one measurement of true/false in your expression.
–
NarfanatorJun 11 '13 at 20:13

2

Just nitpicking, but in !(A + B) <=> !A + !B and -1*(A + B) = -A + -B shouldn't the operator have been flipped from + to * in the second expression?
–
Jeff BridgmanJun 11 '13 at 21:18

Yes. You should use in any case when you feel your code will be more clear. Remember your code should be clear enough so that others can understand without reading your comments inside the code. So it is a good practice to use parentheses and braces. Also keep in mind that it may be depends on the particular practice of your company/team. Just maintain one approach and do not mix.