コーディングスタイルと文章の認識

コーディングスタイルのことを考えるよりコードを書いたほうがいいということはわかっているのだが、コーディングスタイルのことは結構考えてしまう。恋か?

私は割とコーディングスタイルの好みが激しいのだが、自分がなぜそのやり方を好んでいるか、あるいはあまり共感できない意見になぜ共感できないのか、ということを考えるうちに、自分がどういうふうにコードを読んでいるかということが少しずつわかってきた。

スタイルにも賛否両論が激しいものがある。例えば、カラムを縦に揃えるスタイルなんかはかなり意見が割れている。私は縦に揃えるスタイルを好んでいる。

反対派の意見としては、「diffにノイズが混ざる」「使っている言語のフォーマッタが対応していない(のでダルい)」「使っている言語自体が推奨していない(PEP8など)」あたりだろうか。最初の意見はツールの問題だ。diffには--ignore-space-changesというオプションがあり、スペースのみの変更を無視してくれる。他にも、--ignore-brank-linesや、--ignore-matching-lines=REGEXなどの種類がある。活用してほしい。無論、ASTレベルのdiffが取れるツールがあればそれに越したことはないが、今の所知る限り存在しない。フォーマッタの問題は、言語自体の方針などもあるので我慢するしかない場合もあり得る。ただ、後述するが、私は言語自体がスタイルを決めるという姿勢をあまりいいことだとは思っていない。理由は後で述べる。

他にも、一行を80文字に制限するというスタイルがある。私はこれに消極的に賛成で、ピッタリ80文字である必要はないが、80文字を超えてくるなら意味の切れ目で改行してほしいと思っている。目線を大きく動かすのはシンプルに苦痛で時間がかかるし、エディタによって自動的に改行する場合も意味の切れ目までは気にしてくれないからだ。ちなみにvimでは以下のような設定にすることで、改行時にインデントを追加しつつ単語のど真ん中で改行するのも防ぐことができる。これでだいたい大丈夫なのだが、例えば関数の引数は全部下の行に、みたいなことはできない。引数リストの途中で容赦無く改行される。

set wrap
set breakindent
set breakindentopt=shift:4
set linebreak

色々考えたあと、自分がコードを読むときに二次元的にというか、画像として全体の印象を把握しているということに気づいた。普通、物語などの文章を読むときは一文字ずつ文字を追っていくと思う。私もそうする。だが、私は文字を追うよりも前に視野の範囲にあるコード・文章全体の形状を見て、その情報を結構使っているようだ。インデントやブロックで隔離されている部分、空行によって分けられた処理、似たパターンの連続……。

こういうやり方に強く依存していると、自分の慣れたコーディングスタイルから離れたコードを読むときはかなりの認知負荷がかかるようになる。制御構造や操作の塊について、画像的な認識が効かなくなってしまうからだ。そもそも、インデントや全体の統一感、あるいはシンタックスハイライトはこういう第一印象的な認識方法を助けるものなのだと思うのだが、そういう説明をされたことがない。自明だからだろうか? 私が少数派だからだろうか? 私はなんとなく、人類は皆こういう方法でテキストを認識しているものだと思っているのだが、あまり明言されているケースを見たことがない気がする。覚えてないだけかもしれないが。

覚えているケースでちょっとおもしろかったのは以下の記事だ。がっつり同じことを言っている訳ではないが、文字列ではなくコード全体の模様や景色からかなりいろいろなことが推定できる例だ。だが「こういうこともできる」とちょっと面白おかしく言っているような気もするので、もしかすると普通はこういう情報は使わないのかもしれない。

postd.cc

そういえば、日本語の文章には読みやすい漢字・ひらがな比があるという話を聞いたことがある。これは模様が文章全体に緩急をつけて読みやすいリズムを作るということを示唆しているのではないか? 英語の文章では単語を分ける空白が上下に連続しないように気をつけるという話も聞いた気がする。本当かは知らない。しかしコードというものは普通の文章よりもよっぽど模様から構造が見て取りやすくなっている。文章の模様が意識的にせよ無意識的にせよ目に入ってくることを思えば、画像的な認識に頼りがちになるのも無理からぬことだ。

画像的な認識に頼っていて、かつ自分のスタイルを確立してそれに慣れてしまっている場合、その人にとって理解するのが最も負荷が軽くそれゆえ高速になるようなコーディングスタイルが存在することになる。これが、私が言語レベルでコーディングスタイルを統一することに賛成しきれない理由だ。統一されていることは確かに大事だが、個々人の効率を最大化しようとした場合、よりよい解決策があるはずだ。全員が手元では異なるフォーマットを使えるようにすればよい。自動で。これは煽りでなく純粋な疑問から聞いてみたいのだが、コーディングスタイルは一貫していれば何でもいい、という人は二次元的な認識にあまり頼っていないのだろうか。あるいはとても多くのスタイルに対してすでに適合しているのだろうか。

フォーマット問題に対する根本的な解決策はASTを直接保存することだ。編集のときどうするかは置いておいて、こうすればdiffの問題どころか、そもそもフォーマットの問題が解決する。ただ、現状からかなり離れている気がするので(特にASTを直接いじる場合)、そのような移行には時間がかかってしまうだろう。

これの近似的な手段としてフォーマッタを利用することもできると思う。コードフォーマッタはすでに多くの言語に存在している。そして、すでに多数のスタイルが確立してしまったC++では、clang-formatはスタイルをかなり細かくチューニングできるようになっている。これを使えば、ファイルを開く際にエディタ内部で自分が最も効率よく認識できるフォーマット(の近似)にコードを自動でフォーマットしてから表示し、保存するとき、あるいはコミットするときにプロジェクト全体のフォーマットに自動で直して保存できる。このようにすれば、各人がそれぞれ最適なフォーマットでコードを読み書きすることができる。ブラウザで見るときは……clang-formatをwasmにコンパイルすればなんとかなるのではないだろうか。そういうプラグインないんだろうか。あるならちょっと作ってみたいな。ブラウザプラグインの知識ないけど。

こういった理由から、私は比較的新しい言語には推奨フォーマットを決めてフォーマッタを実装するよりも、カスタマイズできるフォーマッタを提供してほしいと思うのだ。プロジェクト全体のフォーマットはプロジェクトのオーナーが決めればいいし、それが気に入らない人も手元やブラウザでは自分の好きなフォーマットに変換できるなら特に不便もない。もちろん、往々にしてファジーな我々人類のフォーマット基準をフォーマッタのパラメータに落とし込むのは難しいことではあるのだけど。