Wednesday, December 4, 2013

Code Readability

Go 1.2が12月1日にリリースされました。 そして、同時くらいに社内のGo readability approverの一員になったので、ちょっとCode Readabilityについて書いてみようと思います。

Google社内では、主要なプログラミング言語について Readability というのが存在します。 「C++のReadabilityを持っている」とは、C++のコードをスタイルガイドに従ったコードを読み書きできる能力があることを意味しています。社内のコードベースと一貫したコードで開発できるということです。Readabilityをもっていない人は、Readabilityを持っている人にcode reviewしてLGTM/Approvalを貰わないとコードをrepositoryにcommit/submitすることができません。

readability approverは、ある開発者がその言語のReadabilityを持っているかどうかを判定する/ある開発者がその言語のReadabilityを持つよう教育する役です。

スタイルガイドは言語ごとに、それぞれの言語の特性にあうように決められています。これらのスタイルは、言語のベストプラクティスや、誤りがちなコーディングを避ける方法を示しています。最初は「ルールがたくさんあって、そんなのいちいち気にしてコードなんか書けない」と思うかもしれませんが、慣れてくるとスタイルガイドにしたがっていないコードに違和感を感じるようになってきます。そしてそういうところにバグが潜んでいることが多いような気がします。

個人的な印象としては…

C++の場合は、かなりGoogle独特のルールがあります。が、code reviewする時に、このスタイルガイドに沿ったコードになっていれば、reviewする範囲をchangeで変更した周辺を見ればすむことがすむ場合がけっこうあるようなかんじです。とはいっても言語の罠が結構あるので、ちゃんとreviewするのはなかなかしんどいです。ツールとしては cpplintがありますし、最近は clang-formatなども使われだしてきているようですね。 C++は言語として自由度が高すぎるというか、これといったスタイル標準がないせいで、例えばChromiumWebKitではだいぶ印象が違って、別の言語というかんじもします。

Pythonの場合は、基本的にはPython標準と似たかんじだったと思います。ツールとしてはpylintがあります。 Pythonとかはdocstringをきちんと書いておかないとコードが増えてきたときに厳しいですね。しかもそれはしょせんコメントなので、実際のコードと一致してなかったりするとバグの温床になってしまいます。 code reviewする時も、コードの断片からコードが正しいかどうか見分けるのは困難です。文字列にしてもstrかunicodeなのか気をつけてないと、"Failure: 'ascii' codec can't encode character u'\xNN' in position N: ordinal not in range(128)."みたいなエラーがカジュアルにでてしまうし。Pythonはコードを書きやすいのかもしれないけど、正しくないコードも簡単に書けてしまう/コードが正しいか間違っているか判断するのが難しいという印象です。ちゃんとやるにはテストも大量に書いておかないとだんだん不安になる言語です。

Go言語の場合、基本的なスタイルはgofmtでそろえてくれます。コンパイラもwarningはださず、なおすべき点があればコンパイラがエラーをはきます。 他にもgovetgolintとかもあってよくある問題はコンピュータがみつけてくれます。 Go言語のReadabilityはidiomをちゃんと使っているかどうかという点になってきます。Go言語にも言語の罠はないとはいいませんが、言語仕様もシンプルなので、コードはだいたい見たとおりになっているのもcode reviewしやすいです。

というかんじで、最近は「非常に短いほぼ使い捨てなスクリプト」ならshellとかPythonで書くこともありますが、main以外の関数とかclassが欲しくなってきたら、もうGo言語で書いたほうがいいと思いますね。簡単なものならgo run hoge.goでそのまま実行できますし。また既にある程度書かれているperformance criticalなC++プログラムとかは、そのままC++で変更・追加していっていますが、一から開発するんならGo言語で書くほうが楽しいですよ。