裏 RjpWiki

文字通り,RjpWiki の裏を行きます
R プログラム コンピュータ・サイエンス 統計学

セイウチ演算子(:=)って今更...

2021年01月17日 | ブログラミング

Python 3.8 になって,使えるようになって感涙にむせんでいる人もいるようなんだけど...

a = [1,2,3,4,5]
if (n := len(a)) > 10:
    print(f"List is too long ({n} elements, expected <= 10)")
else:
    print(f"variable n is {n}")
print(n)

実行結果

variable n is 5
5

しかし,これと同じ機能は多くの言語では古くから使えていた
というか,使えていたので,使い方を間違って問題を起こすこともあった。

R では,:= を使うときにも = を使えば良い。ただし,'(代入文)' のように '( )' でくくることを忘れてはいけない。

a = c(1,2,3,4,5)
if ((n = length(a)) > 10) {
    cat(sprintf("List is too long (%d elements, expected <= 10)\n", n))
} else {
    cat(sprintf("variable n is %d\n", n))
}
print(n)

実行結果

variable n is 5
> print(n)
[1] 5

R では if 文の条件式を ( ) でくくらなければならないので,Python と同じようには見えないかも知れないが,外側の( ) を取り除けば Python のセイウチ演算子と同じなのだ。

Julia だともっとわかりやすいだろう(条件式を ( ) でくくる必要がない)。
Python のセイウチ演算子の位置には,代入演算子 = を使っているだけだ。
セイウチ演算子なんてなくても,ちっとも困らない。

a = [1,2,3,4,5]
if (n = length(a)) > 10
    println("List is too long ($n elements, expected <= 10)")
else
    println("variable n is $n")
end
println(n)

実行結果

variable n is 5
5

古いというほど古くはない C でも以下のようになる。
代入式を(n = sizeof(a)/sizeof(int)) のように ( ) でくくるだけ。

#include
#include
int main(void) {
      int n;
      int a[5] = {1,2,3,4,5};
      if ((n = sizeof(a)/sizeof(int)) > 10) {
            printf("List is too long (%d elements, expected <= 10)\n", n);
      }
      else {
            printf("variable n is %d\n", n);
      }
      printf("n = %d\n", n);
      return EXIT_SUCCESS;
}

実行結果

variable n is 5
n = 5

ところで,R はもっと進んでいるんだ。

a = c(1,2,3,4,5)
if ({n = length(a)} > 10) {
    cat(sprintf("List is too long (%d elements, expected <= 10)\n", n))
} else {
    cat(sprintf("variable n is %d\n", n))
}
print(n)

のように,代入文を { } でくくっても良い
それは,この位置に複文を書けるということだ。

以下のようなこともできる。すきなだけ複数の複雑な式を書ける。

a = c(1,2,3,4,5)
if ({n = length(a); m = 2*pi} > 10) {
    cat(sprintf("List is too long (%d elements, expected <= 10)\n", n))
} else {
    cat(sprintf("variable n is %d\n", n))
    cat(sprintf("2*pi = %f\n", m))
}
cat(n, m)

実行結果

variable n is 5
2*pi = 6.283185
> cat(n, m)
5 6.283185

しかし,同じように { } で複文が書ける C では,この位置に複文を書くとエラーになる。

もっと古い AWK でも同じように1つの文は書けるが,やはり複文は書けない。

BEGIN {
      a = 2
      b = 6
      if ((n = a * b) > 0) {
            print "true", n
      }
      else {
            print "false", n
      }
      print "outer", n
}

実行結果

true 12
outer 12

要するに,新しい演算子を作るかどうかということではなく,文法がどうか(記述されたものをどのように解釈するか)ということになるだろう。

コメント   この記事についてブログを書く
« 数学の問題を Julia で解く | トップ | セイウチ演算子(:=)って今更.... »
最新の画像もっと見る

コメントを投稿

ブログ作成者から承認されるまでコメントは反映されません。

ブログラミング」カテゴリの最新記事