# Operator precedence and code readability

32 messages
12
Open this post in threaded view
|

## Operator precedence and code readability

 Hi! Usually the order of operations in a Lua expression is quite obvious for a human: in "a+b*c" the multiplication is calculated first, in "a|b&c" the calculation starts from bitwise AND. But sometimes a Lua programmer might be confused by default precedence. For example, I'm still making errors like "1<
Open this post in threaded view
|

## Re: Operator precedence and code readability

 On Wed, Jan 6, 2021 at 6:00 PM Egor Skriptunoff <[hidden email]> wrote:Hi! Usually the order of operations in a Lua expression is quite obvious for a human: in "a+b*c" the multiplication is calculated first, in "a|b&c" the calculation starts from bitwise AND. But sometimes a Lua programmer might be confused by default precedence.I wouldn't call "a|b&c" obvious. Yes, I was taught in discrete math class as a freshman that "and" has precedence over "or". But it's not obvious, and not something drilled into every middle school student with mnemonics like "Please Excuse My Dear Aunt Sally" and used unconsciously for years in high school. It's something only comes up occasionally in my experience and so I frequently forget, and now as a college senior, seeing "and" and "or" operations (either logical or bitwise) together without parentheses almost always sends me to the operator precedence section of the documentation to refresh my memory. So I always use parentheses with two or more unlike logical or bitwise operations. For example, I'm still making errors like "1<
Open this post in threaded view
|

## Re: Operator precedence and code readability

 On Thu, Jan 7, 2021 at 2:30 AM Jonathan Goble wrote:"and" has precedence over "or". But it's not obviousIt's obvious because AND has precedence over OR in every programming language.
Open this post in threaded view
|

## Re: Operator precedence and code readability

 You seem to have forgotten the presence of NOT :"NOT a AND b" is not evident in common English where it could mean NOT(a AND b), while programming languages most often mean "(NOT a) AND b". Replace "AND" by "OR", this is the same.With the additional parentheses at least, you won't be fooled by common English, even if "NOT a AND b" has a single interpretation in most programming languages where unary operators like NOT take precedence to binary operators (which is not completely true in Lua, with the exponentiation operator "^" which has higher precedence than the unary minus "-", so that "-2^2" means "-(2^2)" (i.e. the negative value "-4") and not "(-2)^2" (i.e. the opposite value "+4").Usually however, we don't need extra parentheses with "(NOT a) AND b" as we are reading a program and not an English book.Lua however is quite strange with the precedence given to "<<" for bit shifts (wich are comparable to an multiplication with a power of 2), and the concatenation of strings with ".." which has higher precedence than other arithmeric operators "+", "-", "*", "/" (but not the power "^") : this is clearly different from other comparable languages and very counterintuitive, but it forces you to surround your numeric expressions into parentheses before concatenating the string converted from the numeric expression.So you have to write: "0"..(1+2) in Lua to get the string value "03"; with "0"..1+2, you'd get the numeric value 3 and  the expression "x="..1+2 would not return "x=3" but a type mismatch error from an attempt to numerically add the string "x1" (not convertible to a number) and the number 2.Le jeu. 7 janv. 2021 à 00:47, Egor Skriptunoff <[hidden email]> a écrit :On Thu, Jan 7, 2021 at 2:30 AM Jonathan Goble wrote:"and" has precedence over "or". But it's not obviousIt's obvious because AND has precedence over OR in every programming language.
Open this post in threaded view
|

## Re: Operator precedence and code readability

 In reply to this post by Jonathan Goble On Thu, Jan 7, 2021 at 2:30 AM Jonathan Goble wrote:What would you change in the matrix according to your favorite coding style? I would also use parentheses like so: "(not test1) or test2"I agree that "(not x) or y" would look nicer with parentheses.  It seems the "unary" type should behave differently for its two subsets: (#) and (- ~ not)     1st \ 2nd |  or  and   ==   |    ~    &    <<   ..   +    *  unary  ^ -------------+-----------------------------------------------------------         or   | ---  ( )  ( )  ( )  ( )  ( )  ( )  ( )  ( )  ( )  ( )  ( )         and  | ---  ---  ( )  ( )  ( )  ( )  ( )  ( )  ( )  ( )  ( )  ( )         ==   | ---  ---  YES  ( )  ( )  ( )  ( )  ( )  ( )  ( )  ( )  ( )         |    | ---  ---  ---  ---  ( )  ( )  ( )  ( )  ( )  ( )  ( )  ( )         ~    | ---  ---  ---  YES  ---  ( )  ( )  ( )  ( )  ( )  ( )  ( )         &    | ---  ---  ---  ---  ---  ---  ( )  ( )  ( )  ( )  ( )  ( )         <<   | ---  ---  ---  ---  ---  ---  YES  ( )  ( )  ( )  ( )  ( )         ..   | ---  ---  ---  YES  YES  YES  YES  ---  ( )  ( )  ( )  ( )         +    | ---  ---  ---  YES  YES  YES  YES  YES  ---  ( )  ( )  ( )         *    | ---  ---  ---  YES  YES  YES  YES  YES  ---  ---  ( )  ( ) unary - ~ not| YES  YES  YES  YES  YES  YES  YES  YES  YES  YES  YES  ( ) unary #      | ---  ---  ---  ---  ---  ---  ---  ---  ---  ---  ---  ( )         ^    | ---  ---  ---  YES  YES  YES  YES  YES  ---  ---  ---  YES
Open this post in threaded view
|

## Re: Operator precedence and code readability

 In reply to this post by Egor Skriptunoff-2 There is a thorough Lua coding convention from the LuaRocks project https://github.com/luarocks/lua-style-guide This style guide is very picky about code readability. I was expecting to find precedence-related recommendations there, but I've found nothing. Is the problem really not that much?Should I just memorize the Lua precedence rulesand stop whining about "operator precedence hell"? :-)
Open this post in threaded view
|

## Re: Operator precedence and code readability

 In reply to this post by Egor Skriptunoff-2 On Thu, Jan 07, 2021 at 02:00:05AM +0300, Egor Skriptunoff wrote: > Obviously, it's a good idea to include extra parentheses to improve code > readability. You should include extra parentheses whenever a situation turns up that needs you, or somebody else who may have to maintain your code in future, to remember a list of operator precedence to otherwise understand. B.
Open this post in threaded view
|

## Re: Operator precedence and code readability

 Parentheses are free In any programming language, as well as plain text documentation, I almost always use parentheses to indicate the exact order of things. As a corollary, if the parens would end up making the expression unwieldy or too complex then I take that as an indication that the original expression is too complex and I try to rewrite it. Frank
Open this post in threaded view
|

## Re: Operator precedence and code readability

 Since this is probably a matter of opinion, let me add one:Always add parentheses, except for +, -, * and ^, since these are the only ones everybody is supposed to learn in school.Even / can lead to confusion:  a*b/c*d - Usually read by programmers as (((a*b)/c)/d)- Sometimes read by mathematicians as ((a*b)/(c*d)), with / as fraction lineOnce you know multiple programming languages with different paradigms, it becomes pointless knowing all precedence rules.Sometimes you copy some code from one language to another (e.g., prototype with Lua but finally copy some mathematical algorithms to C for performance reasons).repeatuntil (l > (a + b*c)); No bracket required, but readable in one second.Also properly placed spaces significantly improve readability.On Thu, Jan 7, 2021 at 2:15 PM [hidden email] <[hidden email]> wrote: Parentheses are free In any programming language, as well as plain text documentation, I almost always use parentheses to indicate the exact order of things. As a corollary, if the parens would end up making the expression unwieldy or too complex then I take that as an indication that the original expression is too complex and I try to rewrite it. Frank
Open this post in threaded view
|

## Re: Operator precedence and code readability

 Hi: On Fri, Jan 8, 2021 at 10:51 AM bel <[hidden email]> wrote: > Even / can lead to confusion:  a*b/c*d > - Usually read by programmers as (((a*b)/c)/d) > - Sometimes read by mathematicians as ((a*b)/(c*d)), with / as fraction line Am I missing something or did you make a typo ? Because both the "usually" and "sometimes", ignoring underflow issues, seem the same to me ( and different from the "even" line ). Francisco Olarte.
Open this post in threaded view
|

## Re: Operator precedence and code readability

 On Fri, 2021-01-08 at 11:09 +0100, Francisco Olarte wrote: > Hi: > > On Fri, Jan 8, 2021 at 10:51 AM bel <[hidden email]> wrote: > > Even / can lead to confusion:  a*b/c*d > > - Usually read by programmers as (((a*b)/c)/d) > > - Sometimes read by mathematicians as ((a*b)/(c*d)), with / as > > fraction line > > Am I missing something or did you make a typo ? > Because both the "usually" and "sometimes", ignoring underflow > issues, > seem the same to me ( and different from the "even" line ). > > Francisco Olarte. It seems to me that the first one was meant to read as - Usually read by programmers as (((a*b)/c)*d) which is what this expression indeed does as written. -- v <[hidden email]>
Open this post in threaded view
|

## Re: Operator precedence and code readability

 Hi: On Fri, Jan 8, 2021 at 2:29 PM v <[hidden email]> wrote: > On Fri, 2021-01-08 at 11:09 +0100, Francisco Olarte wrote: > > Am I missing something or did you make a typo ? ... > It seems to me that the first one was meant to read as > - Usually read by programmers as (((a*b)/c)*d) > which is what this expression indeed does as written. Yep, that's why I asked the OP for clarification. FOS
Open this post in threaded view
|

## Re: Operator precedence and code readability

 In reply to this post by bel On Fri, Jan 8, 2021 at 12:51 PM bel wrote:Since this is probably a matter of opinionYes, it is opinion-based.And I want to know the mean opinion among Lua programmers. +, -, * and ^, since these are the only ones everybody is supposed to learn in school.Opinions may differ significantly: Schoolkids know nothing except + - * ^Experienced Lua programmers might get used to all Lua precedence rules.I want to find the "happy medium" which could be used as a reasonable coding style guide(and be implemented as the default option in a Lua code formatter)Always add parentheses, except for +, -, * and ^I doubt that over-parenthesizing improves code readability.What about the standard chain of bitwise operators: | & < (a + b*c)); No bracket required, but readable in one second.IMO, this code is over-parenthesized. The usual Lua formatuntil l > a + b*cis more readable to me. Also properly placed spaces significantly improve readability.What does "properly placed" mean?Are you talking about context-dependent insertion of spaces?Input example:f(a+b*c)+g(x*y^z)Usual rules output:f(a + b * c) + g(x * y ^ z)each binary operator is surrounded by spacesContext-independent rules output:f(a + b * c) + g(x * y^z)low priority operators + * are surrounded by spaces, high-priority operator ^ is not.Context-dependent rules output:f(a + b*c) + g(x * y^z)ranking of operators into low- and high-priority depends on the current expression
Open this post in threaded view
|

## Re: Operator precedence and code readability

 > > Since this is probably a matter of opinion > > > > Yes, it is opinion-based. > And I want to know the mean opinion among Lua programmers. My personal take is as follows.  In general, I assume that the following rules are well known and don't need parentheses: - Arithmetic (bar exponentiation) and concatentation operations between them. - posfix > prefix > arithmetic/bitwise > comparisons > logical (and/or) (Posfix operations among them have no ambiguity; idem for prefix.) Everything else is more complex. Some specific cases: - and vs. or: sometimes I would like to not use parentheses in this case, but I am not sure how common is this knowledge among average programmers. - exponentiation: in Lua, it follows the usual mathematic rules, so that -x^2 is equivalent to -x². Again, I am not sure how common is this knowledge, so I am not always comfortable writing that without parentheses. Idem for x^y^z (although that case is rare). - bitwise operations: the rules for bitwise operations among them and against arithmetic operations are far from obvious. Some could be considered broken, due to the inheritance from C (where the rules for &,| are "broken" for historical reasons). So, mostly anything in this case are better written with parentheses. - comparisons among them (e.g, a > b == (c < d)): comparisons probably should be non associative, but that is difficult to implement when the parser is based on precedence tables, as is the case in Lua. Anyway, we should always use parentheses in those cases: (a > b) == (c < d). When in doubt whether some expression is clear, it is better to err on the side of extra parentheses. -- Roberto
Open this post in threaded view
|

## Re: Operator precedence and code readability

 On Fri, Jan 8, 2021 at 10:41 AM Roberto Ierusalimschy <[hidden email]> wrote: > - exponentiation: in Lua, it follows the usual mathematic rules, so > that -x^2 is equivalent to -x². Again, I am not sure how common > is this knowledge, so I am not always comfortable writing that > without parentheses. Idem for x^y^z (although that case is rare). The knowledge may be there, but many (early) computer languages (Fortran, Algol 68, Ada) did not have any right associative operators outside of assignments, and unary operators had the highest priority. Fortran, Algol68 and Ada interpret -x**2 as (-x)². Python uses the same interpretation as Lua (for the ** operator). Languages with a C style syntax (C, C++, Java, Go, C#) don't bother with an exponentiation operator. These are not the only things that can trip you up: the "not" operator in Python has a low priority, just above "and", whereas the "not" in Lua and the equivalent in most languages has the high priority of all unary operators. "not a < b" is interpreted as "(not a) < b" by Lua, and "not (a < b)" by Python. Fortran is similar to Python here. I would suggest using parentheses when in doubt, because mathematicians generally agree on the interpretation of expressions, but programming language designers do not. -- Gé
Open this post in threaded view
|

## Re: Operator precedence and code readability

 In reply to this post by Roberto Ierusalimschy On Fri, Jan 8, 2021 at 9:41 PM Roberto Ierusalimschy wrote:exponentiation: in Lua, it follows the usual mathematic rulesBTW, this is my top 3 pitfalls of Lua precedence rules (in the order of decreasing surprise):#str^2    is not  (#str)^2-x%2-x%3  is not  -x%3-x%21<
Open this post in threaded view
|

## Re: Operator precedence and code readability

 In reply to this post by Egor Skriptunoff-2 You can always follow the rule: When confused and in doubt,    Use parentheses all about. (Taken from Robert Heinlein's   "When in trouble and in doubt,     Run in circles, scream and shout" ) I got taught "Please Excuse My Dear Aunt Sally". Paren, exponent, multiply, divide, addition subtraction, so that is easy, If it's code for just me, then parens when needed, if I'm teaching beginning programmers or someone else may read what I wrote, then all the parens needed to make it clear the order I/they were thinking.     Taking seconds to add extra parens to save hours is a pretty simple choice. Foster
Open this post in threaded view
|

## Re: Operator precedence and code readability

Open this post in threaded view
|