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言語で書くほうが楽しいですよ。

Monday, July 15, 2013

FSIJ月例会: GnuPG

FSIJ理事会、総会の後、FSIJ月例会に参加してきました。 gniibeさんによるGnuPGの"信頼"についての話でした。

そもそもは、大統一Debian勉強会: PGP/GPGキーサインパーティの説明が話を盛りすぎではないかということでした。 そこではこのように書かれています

フリーソフトウェアの世界では、ネット上で自分の存在を保証してもらうために、PGP/GPG を使ったWeb of Trust を構築しています。フリーソフトウェアの開発に参加している方、参加を考えている方はこれを機会に参加してみてはいかがでしょうか。
また、開発者以外の方にとっても、ソフトウェアの配布アーカイブに PGP/GPG 署名やハッシュが添付されていることもあり、 ソフトウェアの入手時の正当性確認の意味でも重要です。
Debian、Ubuntu、CentOSなどでは、パッケージリポジトリの正当性を確認するために、 PGP/GPG を使ったシステムが採用されています。 この信頼性は Web of Trust に基づいているため、Web of Trust の中で各ディストリビューションのリポジトリ管理者とつながることが重要です。
これを読むと「PGP/GPGのWeb of Trustに基づいてパッケージリポジトリの正当性を確認している」ように読めますよね。 そしてその「Web of Trustを強くするためにキーサインしましょう」という呼びかけになっています。

しかし、実際のところPGP/GPGのWeb of Trustに基づいておこなわれる操作はほとんどないのではないかという話です。

Debianの場合は次のようになっているはずです。

まず、apt-getでパッケージを取得する時にGPGの署名の確認をおこなっています。これは/etc/apt/trusted.gpgの鍵でReleaseファイルが署名されているかどうかを確認しています。基本的に/etc/apt/trusted.gpgの鍵が信頼できるものとしています。この鍵への署名はあまり重要ではありません。かなり気にしている人ならばこの鍵が自分の知っている人が署名しているか、もしくはディストリビューションの開発者が署名しているかというのを気にするかもしれません。その場合は/etc/apt/trusted.gpgから鍵をはずすなどの作業をする必要があるでしょう(自分のkeyringからのチェーンをaptがみてくれたりはしない)

その前にリポジトリにいれる時に、開発者は*.changes,*.dscに署名してアップロードします。アップロードされたほうがそれらのファイルがdebian-keyringの中にある鍵で署名されているかどうかを確認しています。debian-keyringにはDebianの開発者の鍵しか入っていません。 ここでもその鍵に署名があるかどうかは関係ありません。

鍵への署名が重要なのは、debian-keyringにいれてもらう時(Debian開発者になる時)です。この時、Debian開発者候補者は、既存のDebian開発者から署名してもらったGPG鍵をもっている必要があります。そのGPG鍵が確かにその人の使っている鍵であるということを保証するためです。 この署名をもらうためにキーサインパーティは、多数の開発者と出会えるよい機会であるといえます。 なお、debian-keyringにいれてもらうには、ほかにもいろいろと条件があります(キーサインは身分証明のステップです)。

そのほかにキーサインが重要なのは、その人と直接のやりとりがある場合でしょう。 gitではcommitやtagに署名する機能があるので、gitでpush/pullする時に相手を検証するのに使ったりもします。

いいかたをかえると、リポジトリの信頼性という意味ではキーサインパーティはあまり意味がありません。/etc/apt/trusted.gpgを信頼するか、debian-keyringを信頼するかにかかっています。この場合信頼するかどうかは署名するかどうかはあまり関係ありません。署名しなくても/etc/apt/trusted.gpgは信頼することになっているからです。

GPGでWeb of trustをやるには、キーサインだけじゃなくてtrust dbをちゃんとやらないといけないんですが、ちゃんとやるのはたいへんですね。

Saturday, April 13, 2013

Go Conference 2013 Spring

Go Conference 2013 Springに参加してきました。

ハンズオンの時間は、放置していたcode.google.com/p/go.net/websocketをいじってました。

プレゼンは「「なぜGoなのか」というところを話してほしい」ということだったので、言語機能の説明よりもどのあたりがいいかを説明してみることにしました。

「最初はキモッって思うかもしれないけど、そのうちかわいく見えてきますよ」というかんじが伝えられたでしょうか。 なんでGoをつかうとうれしいかは、大規模なチームの中で大規模なコードをいじらないとなかなかピンとこないかもしれません。

印象としてはこんなかんじかなー

C
知っている技術者は多い。OOをやるにはめんどい(glibみたいになっていく?)。大規模になってくるとclassとかnamespaceとかないとつらいかんじ
C++
知っている技術者はそこそこ多い。大規模なプロダクトができる(googleのサーバーとかChromeとか)がビルド時間がとてつもなく長くなっていって開発するのがつらい。C++11以前だと(autoとかないと)書くのもめんどいときが多い。
Java
知っている技術者はそこそこ多い。(IDEとかの助けがないと)書くのがめんどい。大規模になってくるとIDEではつらい。JavaにかぎらずJVMベースの言語はJVMのチューニングとかがたいへんぽい。
Python
知っている技術者はそこそこ多い。ちょっとしたプログラムだと簡単。規模がおおきくなってくると詳細をつかむのがむずかしくなってくる(この変数はどういう値(どのclassのobject)になりうるのか? 別のclassのobjectをわたしてもいいのか? とか)。そのうち滅多に通らないコードパスでruntimeエラーで死んで悲しくなる。(つまらないtypoとかだとさらに悲しい)
Ruby
Pythonと似たかんじ。Domain Specific Languageにされてしまったりもするが、そうなるとその方言もしらないと読むのもつらい
JavaScript
表層をしっている技術者は多いが、ディープなところになるとむずかしすぎし、そういうところで問題がおきると調べるのがむずかしい。大規模になるとClosure Compilerとかの annotationしておかないとつらくなってくる。
ErlangとかHaskellとか
Cプログラマにとっては学習コストがたかそう。
Goだとimplicitなことが少ないのでコードを読む負担がすくないのがいいと思います。型が省略されてるのもその式の型を把握するのは難しくないですし(深い推論とかしてないので)。 より詳しくはRob Pike先生のGo at Google: Language Design in the Service of Software Engineering (slides)を読むとよいかと思います。 talks.golang.orgには他にもgo teamのプレゼンがいろいろ置いてあるので見てみることをおすすめします。

発表の資料はhttp://ukai-go-talks.appspot.com/2013/gocon.slide#1に置いてみました。せっかくなのでhttps://code.google.com/p/go.talksをつかってみました。これsyntaxがこんなかんじで、昔のMagicPointを思いだしたりしました…。表現力とかはたいしたことないですが、local版だとplay.golang.orgみたいにcodeの実行ができるので、Go言語のプレゼンをするのには便利です。