連環比較運算式
作者:gugod 發佈於: ,更新於: #perl #raku #python3連環比較運算式這種語法,如 $a < $b < $c
,在數學界是很常見的表示法,一式可以表示多項變數之間的關系,但在程式語言裡似乎並不常看到。
Raku 是在發展最初期就有這種語法了。比方說,以下這程式 num-within
能自 STDIN 中取得數字,並將 $from...$until
這範圍之內的數字印出,範圍之外的則丟棄。
#!/usr/bin/env raku
## Usage: num-within <from> <until>
my ($from, $until) = @*ARGS[0, 1];
for $*IN.lines() -> $num {
if $from <= $num < $until {
say $num
}
}
用起來如下:
# bash -c 'while true; do echo $RANDOM; done' | num-within 100 120
114
165
155
130
161
199
108
115
153
166
...
Python 3 也支援這語法。以下是 num-within
改寫為 python3:
#!/usr/bin/env python3
## Usage: num-within.py <from> <until>
import sys
num_from = int(sys.argv[1])
num_until = int(sys.argv[2])
for line in sys.stdin:
n = int(line)
if num_from <= n < num_until:
print(str(n))
Perl5 終於也在 Perl 5.31.10 版之中加入了一部份之支援,並已於 Perl 5.32 中正式問市。以下為 num-within
改寫為 Perl5
#!/usr/bin/env perl
## Usage: num-within.pl <from> <until>
use v5.31.10;
my ($from, $until) = @ARGV[0,1];
while(defined(my $num = <STDIN>)) {
if ($from <= $num < $until) {
print $num;
}
}
除了檢查數值的上下邊界之外,也可以用來做實做其他的。比方說實做 max3(a,b,c)
(取三變數中最大者)
sub max3($x, $y, $z) {
return $x if $y <= $x >= $z;
return $y if $z <= $y >= $z;
return $z;
}
不過 Perl5 中的實做似乎尚不完美,以下這種表示式在 Raku 與 Python3 的意義與其數學意義相同:
$a < $b == $c < $d
也就是與下等價:
($a < $b) and ($b == $c) and ($c < $d)
但在 Perl5 中被解析為:
($a < $b) == ($c < $d)
看來在 Perl5 中 ==
算符並不能做為連環比較算式中的一節,使得此表示式之意義與其數學上的意義有所差距。從目前 perl-5.31.11 中的 perlop 文件 看來,這算是有明文寫著的一件事(雖然是並非寫得很明白,需要從運算子優先序表格推敲得出)。或許這部份尚有待發展。
2020/09/12 更新:Perl 5.32 確實加入了連環比較運算式之語法。