Hello.
Perl 5.32 (year 2020) introduced a new ability of binary comparison operators. Now they can be chained! (
https://perldoc.perl.org/5.32.0/perldelta#Chained-comparisons-capability ).
And perldoc describes this new usage in:
*
https://perldoc.perl.org/perlop#Operator-Precedence-and-Associativity
*
https://perldoc.perl.org/perlop#Relational-Operators
*
https://perldoc.perl.org/perlop#Equality-Operators
There are some short-circuiting operators in Perl from before 5.32 version:
&&, ||, //, and, or (not
xor).
What is difference between associativity and chainity?
I suggest to distinguish these two attributes of operators as follows:
associativity only sets a direction of operations;
chainity sets an ability to 'communicate' between consecutive operators, in other words - a later operator can influence the behaviour of a former operator.
Then I suggest to improve a table of Perl operators by introducing two more columns: chainity (ability to chain) and ability to short-circuit.
This will help to newcomers and beginners! I have often used these tables of operators from
perlcheat and from beginning of the perlop:
https://perldoc.perl.org/perlop#Operator-Precedence-and-Associativity, because it takes time to remember precedence and direction of associativity. Two new attributes in the table will be more usable than a searching of them through the whole long
perlop document.
In the current table of attributes I find only one column, which contains values:
nonassoc, left, right, chained, chain/na. Chained implies associativity, but it lefts its direction undefined, e.g. in the line: "
chained < > <= >= lt gt le ge" newcomer doesn't know direction. We know - it is left-assoc.
Perl is difficult to memorize and it has long learning curve because of its archaity and many many rules with many exceptions, which makes a life easier, but makes learning/memorizing - difficult. So tables/cheatsheets are useful to have near a hand. E.g. operators 'or' and 'xor' seem similar by their appearance and by their category (both are logical operators), but one has an ability to short-circuit and another - hasn't. This was a surprise for me.
Upd.The surprise was not about short-circuit, but about returning last evaluated value.
I can't test a new perl 5.32 now (
upd. perlbrew isn't working /upd.*, and there are no online IDEs where I could find a new version: all use older versions, including WebPerl:
https://webperl.zero-g.net/democode/index.html which uses 5.28).
But I hope that I will be correct when talking further about new abilities of comparison operators.
So, first of all I guess that new version outputs different results for these two lines of codes:
2 < 4 < 3 and
( 2 < 4 ) < 3. In the first example the chaining of operators occurs and in the second example - ordinary comparisons occurs. First outputs - 0/'', second - 1. Am I wrong? Here parentheses cut a chain of operators: one operator doesn't see another. If second behaves same as first then it would be backwards incompatible.
Only some examples of chained comparisons: "
1 < 3 <= 3 > 0 le 1 gt 0 ---> 1", "
1 < 2 < ... < 9 ---> 1", "
1 ne 2 ne 1 ---> 1".
How can we describe a behaviour of chained comparison operators?
I suggest the following way. If an operator "sees" another operator towards the direction of associativity (i.e. it is chained to it), then it changes it behaviour (btw. becomes overloaded) - it compares both operands and in case of TRUE returns right operand (once evaluated), and in case of FALSE - returns 0/''.
This description allows the last operator to be not chained, so it will behave as usual comparison op (TRUE - 1, FALSE - 0/'').
Chainity implies (requires) associativity, as ability to short-circuit does, but chaining does not imply an ability to short-circuit and vice versa, so I suggest to keep these two attributes separately. Maybe in a future perl such will occur.
By the way, operators
&&, ||, //, and, or are short-circuiting, but they are not chained (i.e. we can put parentheses in left-assoc pattern to "blind" consecutive operators and result will not change).
Also I have an idea (I don't believe that it is good, but I leave it here if someone wants to discuss). That: writer could choose by himself if he wants his operator to look to the next operator (i.e. to make a chain). One way could be to prepend '&' before an operator. So then
$A &< $B &> $C < $D should work as a chain (note no '&' at the last operator).
Once more about tables. From
perlop it is unknown which 'equality' operators can be chained and which can not. This needs a clarification.
Here I'll leave some links to older topics (by me), which can be somehow related to this one:
Pls more operators, e.g. <&&=
'xor' operator is not a sibling to 'or' and 'and'?
UPDATE:
Here is my suggestion of an expanded table (which is a bit incomplete, but I want to show an idea). Note that vertical lines mean that some operators are the same precedence but divided into separate lines:
ASSOC. COND. SHORT-C. CHAINS OP.
left terms and list operators (leftward
+)
left ->
nonassoc ++ --
right **
right ! ~ \ and unary + and -
left =~ !~
left * / % x
left + - .
left << >>
nonassoc named unary operators
LEFT no yes yes < > <= >= lt gt le ge
| LEFT no yes yes == != eq ne ~~
| LEFT no no no <=> cmp
nonassoc isa
left &
left | ^
left yes yes no &&
left yes yes no || //
nonassoc .. ...
right yes no no ?:
right = += -= *= etc. goto last next red
+o dump
left , =>
nonassoc list operators (rightward)
right not
left yes yes no and
| left yes yes no or
| left no no no xor
Upd. Also created a documentation issue asking to expand this table of attributes -- https://github.com/Perl/perl5/issues/18574.
(
*upd. perlbrew failed to install from its download page, but later I found it in Software manager and installed.)
Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
Read Where should I post X? if you're not absolutely sure you're posting in the right place.
Please read these before you post! —
Posts may use any of the Perl Monks Approved HTML tags:
- a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
| |
For: |
|
Use: |
| & | | & |
| < | | < |
| > | | > |
| [ | | [ |
| ] | | ] |
Link using PerlMonks shortcuts! What shortcuts can I use for linking?
See Writeup Formatting Tips and other pages linked from there for more info.