View Issue Details
ID  Project  Category  View Status  Date Submitted  Last Update 

0035417  FPC  Documentation  public  20190418 22:51  20190826 09:03 
Reporter  Kai Burghardt  Assigned To  Michael Van Canneyt  
Priority  normal  Severity  minor  Reproducibility  always 
Status  resolved  Resolution  reopened  
Platform  x86_64  OS  GNU/Linux  OS Version  4.2.0 
Product Version  3.0.4  Product Build  3.0.4+dfsg11 [2017/12/30]  
Target Version  3.2.0  Fixed in Version  3.3.1  
Summary  0035417: reference guide: “precedence of operators” table should be labeled to be incomprehensive  
Description  According to Michael's comment in 0035334 the only table regarding precedence of operators refers to mathematical operators. a) Please label the table accordingly. b) Remove nonmathematical operators (i.e. `as` and `@`) from the table.  
Additional Information  Additionally, I noticed that the remark the exponentiation operator is not defined by default is sort of misplaced. The attached patch suggests a better position and adds the exponentiation operator to the table listing binary arithmetic operators. Furthermore, some wording in the expressions chapter are “suboptimal.” That means expressions aren't “executed” but “evaluated” and the precedence discussion refers to _sub_expressions, not the whole expressions per se. See also my earlier 0035321  
Tags  documentation  
Fixed in Revision  1643  
FPCOldBugId  
FPCTarget  3.2.0  
Attached Files 


ref.tex.patch (4,568 bytes)
 ref.tex~ 20190418 20:38:00.462284415 +0000 +++ ref.tex 20190418 20:38:00.458284356 +0000 @@ 8341,23 +8341,24 @@ \chapter{Expressions} \label{ch:Expressions} \index{Expressions} Expressions occur in assignments or in tests. Expressions produce a value of a certain type. Expressions are built with two components: operators and their operands. Usually an operator is binary, i.e. it requires 2 operands. Binary operators occur always between the operands (as in \var{X/Y}). Sometimes an operator is unary, i.e. it requires only one argument. A unary operator +Expressions occur in assignments or in tests. +They resolve into a value of a certain type. +Expressions are built of two components: operators and their operands. +Most operators are binary, i.e. require 2 operands. Binary operators +occur always between the operands (as in \var{X/Y}). Few +operators are unary, i.e. require only one operand. A unary operator occurs always before the operand, as in \var{X}. When using multiple operands in an expression, the precedence rules of \seet{OperatorPrecedence} are used.\index{Operators} \begin{FPCltable}{lll}{Precedence of operators}{OperatorPrecedence} +\begin{FPCltable}{lll}{Precedence of mathematical operators}{OperatorPrecedence} Operator & Precedence & Category \\ \hline \var{Not, @, unary +, unary , **} & Highest (first) & Unary operators, +\var{Not}, unary \var{+}, unary \var{}, \var{**} & Highest (first) & Unary operators, power\\ \var{* / div mod and shl shr as <{}< >{}>} & Second & Multiplying operators\\ \var{+  or xor} & Third & Adding operators \\ \var{= <> < > <= >= in is} & Lowest (Last) & relational operators \\ +\var{*}, \var{/}, \var{div}, \var{mod}, \var{and}, \var{shl}, \var{shr}, \var{<{}<}, \var{>{}>}} + & Second & Multiplying operators\\ +\var{+}, \var{}, \var{or}, \var{xor} & Third & Adding operators \\ +\var{=}, \var{<>}, \var{<}, \var{>}, \var{<=}, \var{>=}, \var{in}, \var{is} & Lowest (Last) & relational operators \\ \hline \end{FPCltable} When determining the precedence, the compiler uses the following rules: @@ 8365,16 +8366,16 @@ \item In operations with unequal precedences the operands belong to the operator with the highest precedence. For example, in \var{5*3+7}, the multiplication is higher in precedence than the addition, so it is executed first. The result would be 22. +evaluated first. The result would be 22. \item If parentheses are used in an expression, their contents is evaluated first. Thus, \var {5*(3+7)} would result in 50. \end{enumerate} \begin{remark} The order in which expressions of the same precedence are evaluated is not guaranteed to be lefttoright. In general, no assumptions on which expression +guaranteed to be lefttoright. In general, no assumptions on which subexpression is evaluated first should be made in such a case. The compiler will decide which expression to evaluate first based on +The compiler will decide which subexpression to evaluate first based on optimization rules. Thus, in the following expression: \begin{verbatim} a := g(3) + f(2); @@ 8390,11 +8391,6 @@ \end{verbatim} \end{remark} \begin{remark} The exponentiation operator (\var{**}) is available for overloading, but is not defined on any of the standard Pascal types (floats and/or integers). \end{remark}  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Expression syntax \section{Expression syntax} @@ 8728,11 +8724,12 @@ Binary operators are listed in \seet{binaroperators}, unary operators are listed in \seet{unaroperators}. \begin{FPCltable}{ll}{Binary arithmetic operators}{binaroperators} Operator & Operation \\ \hline \var{+} & Addition\\ \var{} & Subtraction\\ \var{*} & Multiplication \\ \var{/} & Division \\ +Operator & Operation \\ \hline +\var{+} & Addition \\ +\var{} & Subtraction \\ +\var{*} & Multiplication \\ +\var{**} & Exponentiation \\ +\var{/} & Division \\ \var{Div} & Integer division \\ \var{Mod} & Remainder \\ \hline \end{FPCltable} @@ 8740,6 +8737,12 @@ expressions as operands, all operators accept real and integer expressions as operands. +\begin{remark} +The exponentiation operator (\var{**}) is available for overloading +(\seec{operatoroverloading}), +but is not defined on any of the standard Pascal types (floats and/or integers). +\end{remark} + For binary operators, the result type will be integer if both operands are integer type expressions. If one of the operands is a real type expression, then the result is real. 

I have applied the patch with some modifications. I readded the @ and as operators, and removed the word 'mathematical' from the table caption. Delphi also treats @ and "as" as an operator, see e.g. http://docwiki.embarcadero.com/RADStudio/Tokyo/en/Expressions_(Delphi) I also added a small sentence to say that the type of an expression is determined by the types of the values and the operators in the expression. 

“I […] removed the word 'mathematical' from the table caption.” Actually, that was my core issue. What I mentioned in the block “Additional information” is just secondary. You wrote in 0035334 “The table lists *mathematical operators*, part of *expressions*.” In 0035321 “[…] this table, which is about mathematical operations.” I don't wanna nail you down to use the word “mathematical.” Maybe “Precedence of symbolic operators” or “Precedence of some operators” are better captions? [The latter one's a joke of course.] My point still persists, that there are operators, that aren't operators (it's just an unfortunate label), but they do exist and apply, and there's competitive precedence between operators and pseudooperators, and yet here, we only have one table summarizing “all” operators' precedence rules. “I readded the […] as operator[…].” In 0035321 you wrote “A typecast is also not an operator.” Why is a /conditional/ typecast an operator anyway then? This is inconsistent. Are typecasts operators, or not? Make up your mind. The argument, that Delphi does something (or doesn't), is moot here. We're talking about FPC's documentation. “I readded the @ […] operator[…].” Alright, I mean, one can write addr(…), too, but only `@` (with {$typedAddress on}) returns /typed/ pointers, so it has an elevated “quality.” So, in order to stay consistent, we should add the hat `^` (as a _de_referencing operator) to the table, too. On Delphi's “expression” wiki page, it is referred to as operator, too. [Don't forget to add a sentence, that the dereferencing operator is the only unary operator that _succeeds_ its operand.] 

competitiveOperatorPrecedence.pas (539 bytes)
program competitiveOperatorPrecedence(input, output, stderr); {$mode objFPC} type compassPoint = (north, east, south, west); operator := (const x: compassPoint) y: string; begin case x of north: begin y := 'N'; end; east: begin y := 'E'; end; south: begin y := 'S'; end; west: begin y := 'W'; end; otherwise begin y := ''; end; end; end; begin // fails, because implicit typecasts have the least precedence //writeLn(concat(north, east)); writeLn(concat(north, string(east))); end. 

I removed "Mathematical" because it is also not a correct term. "not", "and" "or" "xor" are logical operators. The 'is' and 'as' are also not mathematical operators. They are outside of the domain of math, they're in the domain of logic. So, I deliberately do not put such a label on top of the table, exactly so as not to be pinned down on such terms. But they're all operators. You will no doubt think this is a lack of precision: yes, you are right. It is deliberate "vagueness", "wriggle room" or whatever you want to call it. I am aware that there is a lot of inconsistency in the way the terms are chosen, but the inconsistency is there in the language, and I don't think any amount of documentation will fix that. So, there is some 'vagueness'... A consistent language would IMO have to be redesigned from the ground up. But I will inquire about the ^ "operator", though, because I am currently undecided as to whether this should be regarded as the opposite of the @ operator (and hence as an operator) or as an equivalent of the . (dot) notation, indicating membership, in which case it does not belong in this table. Till now I tended towards the latter, but you may be right that it should be regarded as an operator, in which case it should probably be together with the @. As soon as the core members answered, I will fix it (or not :) ) 

Yeah, the word “mathematical” is suboptimal, indeed, yet still it conveys what operators are [supposed to be] in this table. “Operators are nonoverloaded operators that /can/ _change_ a date, or make true/false statements about dates. They do not solely interact with the typing system (no typecasts). They do not solely inform the compiler, how to treat/handle/interpret the concept of a variable (`@` and `^`).” I don't know how the unary plus (sign identity) fits in there, since it doesn't _alter_ anything. But here again, that the plus became an operator is the real problem. I think, Pascal originally defined the /now/ unary plus as part of numerical literals only. You couldn't just put a single plus in front of a numerical variable, it's an error. Mathematical logic _is_ a subdomain of mathematics. I don't see a problem labeling logical operators as mathematical operators. Math doesn't just consist of arithmetic. You can state a whole Boolean algebra, and formalize logic in a “mathy” fashion. I'm not sure about `is` and `as`, but I guess you can make the same argument as well. They both have objects/classes as operands and juggling with (mathematical) objects is math's “thing”. `^` /is/ the reverse operation of `@` (with typed pointers): ``` program addressingOperators(input, output, stderr); {$typedAddress on} var x: integer; begin (@x)^ := 42; writeLn(x); end. ``` The dot notation just indicates an offset, no more. I actually do not say `@` and `^` are operators, confer above. I just said, it would be consistent. By default, when we refer to a variable (by its identifier) we mean its value. `@` and `^` just give “hints” to the compiler how to interpret the concept of a variable (a labeled chunk in memory). 

Corroborating my last point: (In some modes) the `@` has to appear in front of routine identifiers in order to assign them to “procedural” variables. The `@` plays more like a role of being a “hint” for the compiler, that in this case a function/procedure identifier doesn't refer to calling that routine, but its address is requested. 

By the way: `><` is missing in the table. I only hope it is an operator 😉. 

>< is an operator for sets: symmetric difference. And supported. I thought it was at least in the set operator docs. 

more_ref.tex.patch (1,286 bytes)
 ref.tex~ 20190729 20:15:17.637544656 +0000 +++ ref.tex 20190729 20:15:17.637544656 +0000 @@ 8360,9 +8360,9 @@ \seet{OperatorPrecedence} are used.\index{Operators} \begin{FPCltable}{lll}{Precedence of operators}{OperatorPrecedence} Operator & Precedence & Category \\ \hline \var{Not}, unary \var{+}, unary \var{}, \var{**} \var{@} & Highest (first) & Unary operators, power \\ +\var{Not}, unary \var{+}, unary \var{}, \var{@}, \var{**} & Highest (first) & Unary operators, power \\ \var{*}, \var{/}, \var{div}, \var{mod}, \var{and}, \var{shl}, \var{shr}, \var{as}, \var{<{}<}, \var{>{}>} & Second & Multiplying operators \\ \var{+}, \var{}, \var{or}, \var{xor} & Third & Adding operators \\ +\var{+}, \var{}, \var{or}, \var{xor}, \var{><} & Third & Adding operators \\ \var{=}, \var{<>}, \var{<}, \var{>}, \var{<=}, \var{>=}, \var{in}, \var{is} & Lowest (Last) & relational operators \\ \hline \end{FPCltable} @@ 8375,6 +8375,8 @@ evaluated first. The result would be 22. \item If parentheses are used in an expression, their contents is evaluated first. Thus, \var {5*(3+7)} would result in 50. +\item Otherwise, binary operators of the same precedence are leftassociative. +\var{5 * 3 div 7} will evaluate to 2 and not 0. \end{enumerate} \begin{remark} 

Applied the latest patch, thanks for that. 
Date Modified  Username  Field  Change 

20190418 22:51  Kai Burghardt  New Issue  
20190418 22:51  Kai Burghardt  Status  new => assigned 
20190418 22:51  Kai Burghardt  Assigned To  => Michael Van Canneyt 
20190418 22:51  Kai Burghardt  File Added: ref.tex.patch  
20190418 22:51  Kai Burghardt  Tag Attached: documentation  
20190419 10:20  Michael Van Canneyt  Fixed in Revision  => 1600 
20190419 10:20  Michael Van Canneyt  Note Added: 0115669  
20190419 10:20  Michael Van Canneyt  Status  assigned => resolved 
20190419 10:20  Michael Van Canneyt  Fixed in Version  => 3.3.1 
20190419 10:20  Michael Van Canneyt  Resolution  open => fixed 
20190419 10:20  Michael Van Canneyt  Target Version  => 3.2.0 
20190419 17:26  Kai Burghardt  Note Added: 0115678  
20190419 17:26  Kai Burghardt  Status  resolved => feedback 
20190419 17:26  Kai Burghardt  Resolution  fixed => reopened 
20190419 17:26  Kai Burghardt  File Added: competitiveOperatorPrecedence.pas  
20190419 17:27  Kai Burghardt  Note Edited: 0115678  View Revisions 
20190419 18:08  Michael Van Canneyt  Note Added: 0115680  
20190419 18:10  Michael Van Canneyt  Note Edited: 0115680  View Revisions 
20190420 23:56  Kai Burghardt  Note Added: 0115695  
20190420 23:56  Kai Burghardt  Status  feedback => assigned 
20190421 00:55  Kai Burghardt  Note Added: 0115696  
20190421 02:33  Kai Burghardt  Note Added: 0115697  
20190623 11:37  Thaddy de Koning  Note Added: 0116867  
20190729 22:19  Kai Burghardt  File Added: more_ref.tex.patch  
20190826 09:03  Michael Van Canneyt  Status  assigned => resolved 
20190826 09:03  Michael Van Canneyt  Fixed in Revision  1600 => 1643 
20190826 09:03  Michael Van Canneyt  FPCTarget  => 3.2.0 
20190826 09:03  Michael Van Canneyt  Note Added: 0117841 