作者: 機械伯爵
日時: 2002/3/2(10:03)
P-2 インデントブロック論争 〜カッコつけず、頭をさげろ〜

 Python という言語を実際つかって見たとき、誰もが戸惑うのがこ
の字下げによるブロック記述ではないでしょうか。

 とくに、スタイリッシュな LISP 使い *1 には、ブロックにカッ
コを必要としないPythonの記述にノイローゼになるかもしれません
(大嘘)。

 ブロックにブレース ({} のこと) を使わない以上、Pythonはモダ
ンな言語の必須条件ともいえる「フリー・フォーマット」ではない、
ということです。

 なんて旧式な…これだから「教育用言語 *2」はダサいんだ…

 他言語の支持者の嘲笑が目に浮かぶようです。

 う〜ん…でもねえ…

 そういう貴方、ブロックを表現するとき、インデントしてないん
ですか?

 「してない」というなら、コーディングのセオリー *3 を無視し
てるわけですから、あまり誉められたことじゃないですし、「して
る」というなら、カッコを書かないだけ、Pythonって楽だと思うん
ですけどね。

 スタイルが自由、というのはなるほど、コーディングする立場に
あれば確かに便利です。

 しかし、読む立場になればどうでしょう?

 フォーマットが定まっていない文書は、非常に読みにくいのでは
ないでしょうか?(コードを読む人には、未来の自分も含まれるこ
とをお忘れなく)

 強制されるのが嫌い、という方、「ブロックはブレースで囲む」
という強制的なルールは問題ないのでしょうか?

 自分流の美しいスタイルがある、というプライドをお持ちの方、
インデントの幅は自由ですので、かなり自由にデザインできると思
うのですが、まぁ、それで不足というのなら、これは仕方が無いで
しょうね。

 生理的に我慢ならないという方…無理にお薦めはしませんので気
にいったお好きな言語をお使いください(その環境に、十分な能力
があるといいですね)

 さて、好みに関しては色々ありますので、インデントブロックが
嫌いという方には、これはもう仕方がありませんが・・・もし「劣
っている」「無意味な制限である」と考える方がおられるとすれば、
それは誤解だと申し上げたいと思います。

 ブロックをインデントすることで全体のコードが見やすくなるこ
とについて、よもや反対の方はおられませんよね(もしおられるな
ら、私だけでなく、コーディングの見易さのためにインデントを推
奨しておられる無数の方々に反論してください)

 さらに言えば、Pythonでもif文やwhile文で内容が1文であるよう
な場合は、コロンの後ろに記述することでインデントなしに済ませ
ることもできますし、他の言語のように、セミコロンで区切ること
によってマルチステートメント記述も可能ですので、不必要に冗長
になることはまずありません。

 問題は、ブロックのネストがあまりにも深くなったときだとおも
います。

 一応、Pythonはスペース一個でもブロックとして認識しますので、
かなり深いネストまで耐えられるはずではありますが、そうなると、
インデント幅の数を間違えてしまう危険性が無いとは確かに言い切
れませんね(スクリーンエディタなら、カーソルを動かせば確認で
きると思うのですが、自身、インデントの数を間違えた経験は実際
あるので、これが確実だとはとうてい言えません)

 このような場合は、多少のオーバーヘッドは覚悟で(どうせPython
だし*4)、再帰関数や関数オブジェクトのリスト、さらに多彩な例
外処理機能*5といった、Pythonの特殊機能を駆使して書き換えるこ
とができることで、回避できる場合もあります。

※これが可能な場合は、多分コードも見やすくなると思いますので、
  一挙両得でしょう。

 無論、どんな方法を用いてもネストの深さを変えることができな
いアルゴリズムもあるかもしれませんので、そのような場合が頻繁
に起こるような事例では、Pythonはあまり適当ではないのかもしれ
ませんね。

 インデントブロックによる利点については、欠点よりかなり明確
です。

 まず、人間は基本的にナマケモノである、ということです。

 「つい気を抜いて」見づらいコードを書いてしまうことはままあ
る、ということです。

 本来、インデントするくらい、いくらの労力も要らないはずなの
に(貴方がオートインデント機能の無いエディタをこよなく愛して
いるというのなら、撤回いたします)、しなくても良いとなれば、
手を抜くのが人間というものです(・・・え? 私だけ?)

 というわけで、フォーマット強要の窮屈さは、そのコードを将来
見るであろう他の人や未来の自分にちゃぁんと返ってくるのです。

 また、インデントは「付け忘れ」ることも、あまりありませんし、
見た目ですぐわかります(インデントの幅が極端に小さければ別で
すが)

 カッコの付け忘れによるバグよりは、多分見つけやすいと思われ
ますがいかがでしょう?

 その上、ブレースを入力するためにシフトキーを一々押すより、
スペースキーやタブキーを押す方が、多分楽でしょう。

 負担減は、「努力」とは違って、ちゃんとした問題解決方法の一
つとして認められています。

 他のところでの負担は、このインデントブロックによる負担減で、
かなり相殺されていると私は思います。

 言語の設計思想はさまざまですし、どれが良い、どれが悪いとは
一概にはいえませんが、少なくともPythonが、人気の無かった(ら
しい・・・けど、私も実は知らない)ABC言語から受け継いだこの特
徴については、私はソフトウェアのバグを減らす非常に上質なアイ
ディアだと思います。

※なお、Pascalのようなbegin-endブロックや、Effelのような
  HEADER-end形式のほうが、最終的には見やすくなる、という意見
  については、その通りだと思います。特にEffelタイプは合理的で
  いいですよね。ただし、これはちゃんとインデントして書いた場
  合に限られますので、Pythonのように「ある一定の可読性は強制
  的に確保する」という思想とは別方向だと思われます。

 というか、一度慣れると、このインデントブロック方式は病みつ
きになります*6。

 よって、誰かが言っていたように、C++のソースを書くときに、セ
ミコロンやブレースを良く忘れる、という弊害は確かにあります
(汗)ので、プロの方にはちょっとデンジャラスかも・・・。



*1 スタイリッシュなLISP使い
 意味のわかった方………ほんの冗談ですので、許してください
(わからなかった方………LISPはカッコを多用する(つける)言語
です)。

*2 教育用言語
 Pythonのインデントブロックは、教育用のABC言語に由来するもの
だとGuidoさんは語っています。有名な言葉に「教育用にも使えるも
のは、教育用にしか使えない」というのがありますが、「実用に使
えないものは、教育用でも使えない」と、私は思うんですけどね。
少なくとも私は「教育用」のポケコン(SHARP PC-G850S)とか、実用
として愛用してます(中途半端なCコンパイラ機能はいらんけ
ど・・・)

*3 コーディングのセオリー
 少なくともフリーフォーマットの言語で、「できる限り、ブロッ
クがわかりやすいようにインデントする」ことを勧めていない教科
書を、私は見たことがありません。

*4 どうせPythonだし
 Pythonの長所に、実行速度とメモリサイズの省スペースを挙げる
人はまずいません。もっとも実際は、スクリプトサイズ自身は、実
行環境の標準モジュールを利用すれば、かなり小さくなると思いま
す。しかし、並外れたPythonの実行速度の遅さについては、どんな
コアなPythonマニアであっても認めるところでしょう。まぁ、ハー
ドウェアの進歩はめざましいし、速度が最重要の問題をPythonで片
付けようとするなら、その考え方自体が問題です。

*5 例外機能
 正しくは例外処理機能。Pythonは、Javaのように言語仕様として
例外処理ができるようになっています。そしてやはりJavaのように、
例外処理は「エラートラップ」としてだけでなく、積極的に使うこ
ともできます。というか、それを使わないと、goto文が一切使えな
い(Javaのように、continue文やbrake文にラベルをつけることもで
きない)ため、多重ループから抜け出す時など非常に苦労すること
になるでしょう。

*6 慣れると・・・
 どんな言語だろうと、プログラムをしたことがある人なら、一通
りのPythonの文法は、1時間もあれば使えるようになると思われま
す。プログラムの経験が無くとも、1日もあれば、十分じゃないか
な? ですから「慣れれば簡単ですが、慣れるまでに膨大な時間が
かかります」といったような、詐欺のような話ではありませんので、
念のため。

2002.03.02 機械伯爵