http://qs1969.pair.com?node_id=98812


in reply to Operator Precedence

Learning precedence is a good thing. Obviously, as with any computer language this is important, and there's just enough quirks with perl's table (from it's unique operators) that you do need to learn where these fit in.

Learning how to use parathesis less and operator precedence more is, IMO, equivalent to the progress one makes in their prose writing as they advance through school. Sentence structure become more advance, less common words are used more, etc. This is partially due not only for the writer to able to convience his/her message better, but reflexively, for the writer to review and critique their own work. If the writer users structure and words too complexe for them to understand, they usually go back and change it. For example, a common example is the compound sentence; it's nearly always better to go back and break that into multiple sentences if the meaning is not readily understood. However, well-written prose writers can effectively use complex sentences because they have learned the subtlies needed to help readers parse and understand the sentence correctly.

With any language with operations, the same is true; the typical pattern is for most new programmers to parathesize every expression so that the programmers him/herself can understand what the code does when they review it again. But as the coder progresses, and understands where parenthesis are unnecessary, they will start to avoid them, sometimes resulting in cleaner code that still can be understood by all. But there are still times that I would consider using parenthesis in order to convey understanding in a program even though I could not use them and get the same expected result. For example, to test whether a point ($x, $y) might be in a bounding box, I could use:

if ( ($x >= $x_min ) && ($x <= $x_max) && ($y >= $y_min) && ($y <= $y_ +max) ) { ... }
Or I could use:
if ( $x >= $x_min && $x <= $x_max && $y >= $y_min && &y <= &y_max ) { +... }
Or I could use:
if ( ( $x >= $x_min && $x <= $x_max ) && ( $y >= $y_min && $y <= $y_ma +x ) ) { ... }
While all 3 of these will do the same inequality tests, I personally feel that the last option is the easiest to understand at a glance (that is, requiring minimal parsing of code to understand the intent of the programmer). The first case has a lot of parenthesis and it's easy to see what the specific tests are but not the whole picture, while the second case, it takes a bit of time to figure out what are the test conditions and what are the boolean operators.

But a lot of this boils down to personal preference, the coder's workplace environment, and how much maintainence and code upkeep will be done when the programmer is long gone. If I was in a shop with several perl newbies, I'd be tempted to use option 1 above over option 3 as a new programmer would understand it better (breaking the complexe into several smaller parts). But if the code was only for my use, it would most likely be 2.

So learning the operator precedence table is important. Knowing how to use parenthesis is important. But one of the defining qualities of a good programmer is one that knows how to combine these aspects into code that easily flows from the perverbal page to the reader's mind without syntax getting in the way. Removing all parenthesis for less characters in a file is a nice worthy goal , but the end result may not be as clear as one that uses just the right amount of parenthesis to help convey meaning.

-----------------------------------------------------
Dr. Michael K. Neylon - mneylon-pm@masemware.com || "You've left the lens cap of your mind on again, Pinky" - The Brain

Replies are listed 'Best First'.
Re: Re: Operator Precedence
by tomazos (Deacon) on Jul 22, 2001 at 17:58 UTC
    I guess a corollary of my meditation is that programmers may be purporting to use paranthesis to help document their code, where in fact they are using them because they have not bothered learning the precedence table - and using them "just to be safe".

    Once you know the precedence table, this:

    $x >= $x_min and $x <= $x_max and $y >= $y_min and &y <= &y_max

    ...looks the same as this...

    ($x >= $x_min and $x <= $x_max) and ($y >= $y_min and &y <= &y_max)

    ...and is no easier to read. In fact I would go so far as to say the last example is slightly harder to read because of the extra parentheses.

    In short, I think that no reader benefits from "documentary" parenthesis if they know the precedence table - and a programmer that doesn't should be told to spend the few hours it takes to learn it - rather than the rest of us constantly worrying about them when we code.

      Precedence is not the issue in comparing
      $x >= $x_min and $x <= $x_max and $y >= $y_min and $y <= $y_max
      with
      ($x >= $x_min and $x <= $x_max) and ($y >= $y_min and $y <= $y_max)
      Neither will work if and has higher precedence than &lt;= and &gt;=!

      The issue with the extra brackets here is to add a structure to the code that simplifies understanding. Instead of having to understand 4 independent logical tests, I have to understand 2 logical tests, then combine them. And once I've worked out the first test is "$x is between $x_min and $x_max", the second test is much easier to work out.

      An alternative way to produce the division is simply by using a line break:

      $x >= $x_min and $x <= $x_max and $y >= $y_min and $y <= $y_max
      also makes the analogy easier.

      In any case, a much nicer way to write an interval test (if you're worried about readability) is to put $x on the inside, and keep all comparisons using the same direction:

      $x_min <= $x and $x <= $x_max and $y_min <= $y and $y <= $y_max
      I agree that there are cases where a programmer will use extra, unneeded parenthesis as to avoid any problems with the operator precedence table, and to be truthful, I don't know it by heart. But there are cases that I know for sure (e.g. that boolean && and || take precedence over inequality operators, or that = is weaker than =~), and I'll take advantage of them when possible. And, more importantly, I know where to find this table if I absolutely need it to understand code. (This is my biggest piece of advice that I can give from going through an engineering advanced degree: it's not what you know, but knowing where you can find it if you don't know.).

      I think the assumption that no reader benefits from documentary parens is assuming that all code readers are highly skilled in the first place, and this is obviously false. Programming is a multifaceted skill, and not only requires writing good code, but being able to read code, though this is a skill that I've seen lax in CS education. Even a newbie programmer that has taken the time to learn the precedence table may find themselves stuck on code that lacks any other 'aids' for understanding, either in the form of comments or grouping parens.

      That said, I think it's important moreso to present code as close to prose as possible rather than to distill it down to a mechanical efficiency, because we has humans tend to think on the language level rather than the mathematical one. And typically with languages, the way the mind works is to soak in phrases and small sets of words instead of either the entire sentence at the whole time or each individual word, so presenting thoughts in concise but descriptive bits can provide the maximum transfer of information from the page to the mind. For example, in the first statement I have above, I have several concise phrases but only until I've read the entire line is the meaning clear because I had to go back and think about what the interplay between the various phrases are. In the second, I cannot identify such phrases, so I take it in chunks; the meaning is still there, but from a mind's eye, parsing it is not apparent. The final example has two obvious and concise phrases, *and* both are very descriptive; I know that I'm looking for $x between two values and $y between two values. I would think that most readers would understand the intent of this code faster than the other cases. Of course, not everyone is average, and it is apparent in your (tomazos's) case, that your mind focuses not on the phrases as donated by parens but on the operators and variables. Thus, you might find your understanding improved by reducing the extra weight of parens.

      However, before you go stripping all the parens from your code where needed, make sure you understand what the intended audience of the code is. Your workplace may have programming guidelines that override these. If you have to share code with cow-workers who think more in the overall meaning than the individual pieces, they may become annoyed with you everytime a new piece of your code shows up for development. If you give your code away and don't expect anyone to look at it until after you have long left the site, is the code sufficient enough to stand on its own without your input for others to understand? Of course, anything that is completely for your own benefit, you can do what you want, but if more than a few sets of eyes will ever look at the code, it's better to aim for a treatment of the code that will satisify the bulk of those that look at it, even if it means that the code doesn't look good to you.

      -----------------------------------------------------
      Dr. Michael K. Neylon - mneylon-pm@masemware.com || "You've left the lens cap of your mind on again, Pinky" - The Brain

      I claim that the two conditions don't look the same. They do to the compiler of course, but not to me.

      In this case the second tells me the intent of the command whereas the first only tells me the command.

      The purpose of the extra parentheses isn't to instruct the compiler, it is to instruct me. And it's not to instruct me in what specific sequence of operations the compiler is being told to execute, but to tell me something about the real problem being solved, i.e. 'is the point in the box?'.

      And this is a diferent question than 'Is X both less than the maximum x and greater than the minimum x while at the same time, Y is less than the maximum y and greater than the mimimum y?'

      You may ask, well, if the compiler thinks they're the same, then what's the difference? Or you may not, but let's assume you did. :)

      I answer that source code is meant to be read by the compiler *and* humans. It therefore must serve two purposes, to correctly instruct the processor in the sequence of operations to be performed, and to instruct the human who reads it.

      Many humans find 'Is the point in the box?' far more digestible than 'Is X less than ... and ... and ... '

      For me, the 'documentary' parentheses make if far easier to see the question as an instance of the first and not the second.