123

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 precedence 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 compelling arguments in favor or against including the extraneous parentheses?
Does practical experience suggest that including them significantly improves readability?
Or is wanting them a sign that a developer really needs to sit down and become conversant in the basics of their language?

19
  • 94
    I may be lazy, but I prefer to have parentheses in most of such situations for readability. Jun 11, 2013 at 14:16
  • 6
    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 B
    Jun 11, 2013 at 14:31
  • 18
    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.
    – Reactgular
    Jun 11, 2013 at 14:36
  • 20
    @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. Jun 11, 2013 at 21:40
  • 3
    @timgoodman, sure in c; but not in SmallTalk or psuedocode or whiteboard interview, all of which have different amorphous rules Jun 12, 2013 at 3:04

15 Answers 15

143

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).

9
  • 3
    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 B
    Jun 11, 2013 at 21:05
  • 9
    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.)
    – LarsH
    Jun 12, 2013 at 13:33
  • 1
    @LarsH, thanks, I added this explicitly to the answer.
    – user82096
    Jun 12, 2013 at 13:36
  • 13
    +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.....
    – mattnz
    Jun 14, 2013 at 3:24
  • 3
    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 B
    Jun 14, 2013 at 11:18
95

It matters less whether you are confident in your grasp of the language. What matters more 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.

18
  • 76
    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. Jun 11, 2013 at 16:01
  • 36
    There is such a thing as too many parenthesis -- you're obviously not a lisper ;)
    – paul
    Jun 11, 2013 at 17:12
  • 20
    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. Jun 11, 2013 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.
    – haylem
    Jun 11, 2013 at 23:20
  • 16
    @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.
    – Brendan
    Jun 12, 2013 at 5:09
34

Yes

You should always use parentheses... 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 parentheses. This affected hundreds of people over a two week period.

Real World Reason

I inherited a main-frame application. One day, out of the 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 whitespace and line breaks to make the code more readable. I noticed, in some cases, there were if conditions that combined AND and OR statements and it wasn't clearly distinguishable what data was being ANDed and what data was being ORed. So I started putting parentheses 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 happened. The error had jumped passed the original line of code and was now further down. So I continued, separating 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 expressions from left to right regardless. The new version of the compiler also evaluated expressions from left to right but ambiguous code, meaning unclear combinations of AND and OR 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 conjunction with each other.

Simplified Example

`IF Product = 191 OR Product = 193 AND Model = "ABC" OR Product = 201 OR Product = 202 AND Model = "DEF" ...` (code littered with several of these)

This is a simplified version of what I encountered. There were else conditions with compound boolean logic statements as well.

I remember changing it to:
`IF ((Product = 191 OR Product = 193) AND Model = "ABC") OR ((Product = 201 OR Product = 202) AND Model = "DEF") ...`



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 offloaded 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.

22
  • 25
    That seems like a better illustration of why it's important to have a good compiler.
    – ruakh
    Jun 11, 2013 at 19:35
  • 7
    @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.
    – ruakh
    Jun 11, 2013 at 20:55
  • 5
    @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. Jun 11, 2013 at 22:06
  • 3
    Great story, but I agree that it is not a reason to use parentheses. and/or precedence is nearly universal and about the least likely thing to change that one could think of. If you can't rely on consistent behavior for such a standard, basic operation, your compiler is garbage and you are hosed no matter what you do. Your story is 100% a compiler problem and 0% a code problem. Especially given that the default behavior was simple left-to-right evaluation--order would always be clear, so why would anyone use parentheses?
    – user82096
    Jun 12, 2013 at 12:54
  • 7
    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.
    – LarsH
    Jun 12, 2013 at 13:38
19

Yes, if there are mixed 'and' and 'or'.

Also good idea to () what is logically one check.

Though best is to use well-named predicate functions and evict most checks and conditions there, leaving if simple and readable.

1
  • 6
    True, there's a very good chance a AND b probably should be replaced with either a function or pre-calculated boolen value that has a more descriptive name.
    – Jeff B
    Jun 11, 2013 at 14:30
18

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.

3
  • 1
    +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". Jun 12, 2013 at 13:40
  • 2
    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. Jun 12, 2013 at 13:48
  • 5
    @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. Jun 12, 2013 at 19:57
9

As I see it:

YES Pros:

  • Order of operations is explicit.
  • Protects you from future developers who don't understand order of operations.

YES Cons:

  • May result in cluttered, difficult to read code

NO Pros:

  • ?

NO Cons:

  • Order of operations is implicit
  • Code is less maintainable for developers without a good understanding of order of operations.
6
  • Well said, though I think "May result in cluttered, difficult to read code" is rather subjective. Jun 11, 2013 at 14:42
  • 2
    How does making the semantics of your code explicit make it difficult to read? Jun 11, 2013 at 14:44
  • 1
    I agree with the others in questioning your "Yes Cons". I think it is almost always the opposite.
    – user82096
    Jun 11, 2013 at 14:56
  • @Frustrated As subjective as the opposite claim. Meaning, not at all, really. Just hard to measure. Jun 11, 2013 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.
    – LarsH
    Jun 12, 2013 at 13:45
3

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...

2
  • 7
    If you're going to do that, why not ab = a AND b?
    – Eric
    Jun 11, 2013 at 21:02
  • 1
    Perhaps because ab shall remain unchanged if not a AND b.
    – Armali
    Aug 7, 2015 at 6:30
3

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.

11
  • 2
    "This is very uncommon": According to Stroustrup2013, C++11 seems to have different precedence of AND and OR (p. 257). Same for Python: docs.python.org/2/reference/expressions.html
    – Dirk
    Jun 11, 2013 at 19:26
  • 12
    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".
    – ruakh
    Jun 11, 2013 at 19:34
  • 1
    I agree with ruakh and looked it up for C++11, python, matlab and java.
    – Dirk
    Jun 11, 2013 at 19:36
  • 3
    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.
    – Kaz
    Jun 12, 2013 at 7:53
  • 3
    @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. Jun 12, 2013 at 19:51
1

As everyone said, use parentheses everytime it makes the expression more readable. However if the expression is complicated I'd advise to introduce new functions for the subexpressions.

0

Or is it a sign that a developer needs to really sit down and become confident in the basics of their language?

If you strictly use language in singular, maybe. Now take all the languages you know, from ages old to most modern, from compiled to scripting to SQL to your own DSL you've invented last month.

Do you remember the exact precedence rules for each of these languages, without looking?

2
  • 1
    And as @Cape Cod Gunny above noted, even if you think you know the language cold, the compiler/run-time might change below you.
    – Jordan
    Jun 11, 2013 at 19:26
  • @Jordan That depends on the language. If it is an esoteric homebrew, or pre-alpha, it might. If it is undocumented, how would you know what is by design, what is a bug, and what happens because it's tuesday? Somewhat mature languages, especially if standardized or at least ubiquitous? Outside the really dark corners, get real. Nov 2, 2021 at 16:01
0

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.

0

"Should I use parentheses in logical statements even where not necessary."

Yes, because two people will find them helpful:

  • The next programmer, who's knowledge, competency or style may be different

  • The future you who returns to this code at some later date!

0

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.

0

• I just got back from your funeral. (Sorry about that bread truck, pal ...)

• Or maybe, you just don't work here anymore, and you've changed your phone number.

• I have never seen your code before. Among tens of millions of lines of stuff, I just encountered yours.

• The fires of business urgency are breathing down my neck. "Pres-sure!"

• So ...

"Anything that you can do to make your code more clear(!) is priceless!"

• Because, "here's what keeps me up at night, because it's cost me a lot of sleep and my employer a lot of money." I glance at a line of code, think that I understand what it is doing, but I am wrong. "This WAS the bug that I was looking for, and I just missed it."

• Therefore, "please write your code stupid-simple clear, and accompany it with lots of comments. Thank you very much. "The compiler or interpreter doesn't care either way, but I do, because I have to!"

• My all-too-often pounded forehead will also thank you. "D'oh" is not something that I wish to say!

-1

Complex conditionals are "boolean algebra", which you write in some ways that, well, make it look pretty much exactly like algebra, and you'd definitely use parens for algebra, wouldn't you?

The really useful rules are the negation ones:

!(A || B) <=> !A && !B
!(A && B) <=> !A || !B

Or, in a little clearer format:

!(A + B) <=> !A * !B
!(A * B) <=> !A + !B

which is really clearly just algebra when written as:

-1*(A + B) = -A + -B
-1*(A * B) = -A * -B

But we can also apply the thinking for algebraic simplification and expansion:

(A && B) || (C && D) => 
((A && B) || C) && ((A && B) || D) => 
(AC && BC) && (AD && BD) =>
AC && BC && AD && BD

although in code you have to write:

(A||C) && (B||C) && (A||D) && (B||D)

or, in a little clearer format:

(A + B) * (C + D) => 
((A + B) * C) + ((A + B) * D) => 
(AC + BC) + (AD + BD) =>
AC + BC + AD + BD

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".

5
  • 2
    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?
    – Derek
    Jun 11, 2013 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.
    – Narfanator
    Jun 11, 2013 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.
    – Narfanator
    Jun 11, 2013 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 B
    Jun 11, 2013 at 21:18
  • I agree: "in the pressure of the moment, don't make me CARE about "Boolean Algebra" when you could have pressed the "(" and ")" keys just a few more times and made both your logic and your intentions perfectly CLEAR to your anonymous successor ... another person whom you will never meet, but whose back is probably against the wall. Nov 2, 2021 at 15:40

Not the answer you're looking for? Browse other questions tagged or ask your own question.