とくにあぶなくないRiSKのブログ

危ないRiSKのブログだったかもしれない。本当はRiSKだけどググラビリティとか取得できるIDの都合でsscriskも使ったり。

プログラム言語を考える (8)

吐き気がする。いい加減寝ないと。
Pythonの意味のあるインデントはすばらしいが,ワンライナーには使えない。
C/C++の{}は正しくインデントしていないと読み間違える。
以下,続きを読めるようにする。 起きた。読めるようになった。以下,問題点をだらだらと解説し,最後に解決策を挙げる(かもしれない)。

C/C++

C/C++のぶら下がりif

C/C++のぶら下がりifに文を追加したときに,インデントをミスったためにバグを出すのは当たり前だ。

if (n > 100)
    puts("100を越えてはいけません。");
    n = 100; // この行を追加。ifの条件に関係なく必ず実行される。バグを生み出す。

人間にはそう見えるのだから。

対処療法? {}

常に {} を書くのが防御的プログラミング?C言語の掲示板に張り付いていると { と } の対応が取れてないコードを書くやつはたくさんいるぞ。

#include <stdio.h>
int main(int argc, char**argv)
{
    int c;
    while ((c=getchar()) != EOF)
    {
        int i;
        for (i = 0; i < argc; ++i){
        {
            putchar(c);
            putchar(toupper(c));
        }
    }
    return 0;
}

↑は意図的に書いたコードだが,こんな感じでコンパイルエラーが出ていつまでも悩んでいるやつもたくさんいる。インデントだけを見れば正しいように見えるからだ。それが直感的だからだ。

ここまでのまとめ

C/C++がやってることは人間様の感覚の全く逆だ。全然人間が楽できない。人間がC/C++にあわせてる。いかれてる。

Pythonワンライナー

Pythonでは簡単にワンライナーが書けない。それは多くの場合,改行とインデントが強制される*1からだ。
西尾泰和のブログ: Pythonでワンライナーを作成する際のノウハウ集
「ノウハウ」って,すでに挙げた if のぶら下がり対処と根本では何ら変わらないバッドノウハウのような気がしてならない。

解決策

ワンライナーを書くとき {} を使う。そうではないとき,見やすく改行するし当然インデントもつけるので,インデントがブロックを表せばいい。そのとき {} は不要。
これで全部解決じゃね?どうよ?このアイディア。
以下,Halife擬似コード:

if (n > 100)
    puts("100を越えてはいけません。");
    n = 100; // この行を追加。ここは n>100のときにのみ実行される。
#include <stdio.h>
int main(int argc, char**argv)
    int c;
    while ((c=getchar()) != EOF)
        int i;
        for (i = 0; i < argc; ++i)
            putchar(c);
            putchar(toupper(c));
    return 0;

Pythonっぽくすっきりする。論理構造が分かりやすいじゃないか。コンパイルエラーも出ないし。(Halifeコンパイラではね。)
次にワンライナーなコードについて説明し…たいところだが,こちらは割愛。私がワンライナーを書けないからだ。(←ダメじゃん。)

*1:あってるよね?