View Issue Details

IDProjectCategoryView StatusLast Update
0035417FPCDocumentationpublic2019-08-26 09:03
ReporterKai BurghardtAssigned ToMichael Van Canneyt 
PrioritynormalSeverityminorReproducibilityalways
Status resolvedResolutionreopened 
Platformx86_64OSGNU/LinuxOS Version4.2.0
Product Version3.0.4Product Build3.0.4+dfsg-11 [2017/12/30] 
Target Version3.2.0Fixed in Version3.3.1 
Summary0035417: reference guide: “precedence of operators” table should be labeled to be incomprehensive
DescriptionAccording 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 non-mathematical operators (i.e. `as` and `@`) from the table.
Additional InformationAdditionally, 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 “sub-optimal.” 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
Tagsdocumentation
Fixed in Revision1643
FPCOldBugId
FPCTarget3.2.0
Attached Files
  • ref.tex.patch (4,568 bytes)
    --- ref.tex~	2019-04-18 20:38:00.462284415 +0000
    +++ ref.tex	2019-04-18 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 left-to-right. In general, no assumptions on which expression
    +guaranteed to be left-to-right. 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.
    
    ref.tex.patch (4,568 bytes)
  • 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.
    
  • more_ref.tex.patch (1,286 bytes)
    --- ref.tex~	2019-07-29 20:15:17.637544656 +0000
    +++ ref.tex	2019-07-29 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 left-associative.
    +\var{5 * 3 div 7} will evaluate to 2 and not 0.
     \end{enumerate}
     
     \begin{remark}
    
    more_ref.tex.patch (1,286 bytes)

Activities

Kai Burghardt

2019-04-18 22:51

reporter  

ref.tex.patch (4,568 bytes)
--- ref.tex~	2019-04-18 20:38:00.462284415 +0000
+++ ref.tex	2019-04-18 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 left-to-right. In general, no assumptions on which expression
+guaranteed to be left-to-right. 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.
ref.tex.patch (4,568 bytes)

Michael Van Canneyt

2019-04-19 10:20

administrator   ~0115669

I have applied the patch with some modifications. I re-added 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.

Kai Burghardt

2019-04-19 17:26

reporter   ~0115678

Last edited: 2019-04-19 17:27

View 2 revisions

“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 pseudo-operators, and yet here, we only have one table summarizing “all” operators' precedence rules.



“I re-added 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 re-added 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 de-referencing operator is the only unary operator that _succeeds_ its operand.]

Kai Burghardt

2019-04-19 17:26

reporter  

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.

Michael Van Canneyt

2019-04-19 18:08

administrator   ~0115680

Last edited: 2019-04-19 18:10

View 2 revisions

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

Kai Burghardt

2019-04-20 23:56

reporter   ~0115695

Yeah, the word “mathematical” is sub-optimal, indeed, yet still it conveys what operators are [supposed to be] in this table.

“Operators are non-overloaded 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 sub-domain 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).

Kai Burghardt

2019-04-21 00:54

reporter   ~0115696

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.

Kai Burghardt

2019-04-21 02:33

reporter   ~0115697

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

Thaddy de Koning

2019-06-23 11:37

reporter   ~0116867

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

Kai Burghardt

2019-07-29 22:19

reporter  

more_ref.tex.patch (1,286 bytes)
--- ref.tex~	2019-07-29 20:15:17.637544656 +0000
+++ ref.tex	2019-07-29 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 left-associative.
+\var{5 * 3 div 7} will evaluate to 2 and not 0.
 \end{enumerate}
 
 \begin{remark}
more_ref.tex.patch (1,286 bytes)

Michael Van Canneyt

2019-08-26 09:03

administrator   ~0117841

Applied the latest patch, thanks for that.

Issue History

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