まつもとゆきひろ氏が語る「ビューティフルコード」セミナーに行って来た
まつもとゆきひろが語る「ビューティフルコード」×「プログラマ35歳定年説」に行ってきました〜。今年初めて行ったイベントなのですが、とてもいいお話を聞くことができました。美しいコードとはどのようなものか、またそのようなコードを書けるようになるためにはどうすればいいのかというお話でした。
以下、まとめになります。僕のメモを元にしたので、まつもとさんが話された内容と多少ズレがあるかもしれません。
そもそもコードとは何か
「コードの美しさとは」という前に、そもそも「コード」とは何か。
ソフトウェアの作成はものづくりではない
コードは工業製品ではない。コードは、車とかと同じ工業製品だと思われることが多く、例えば次のような勘違いがある。
- 日本は「ものづくり」が得意だ。だからソフトウェアも「ものづくり」として取り組めばいい
- 車のように、ソフトウェアも部品をどんどんコピーして組み合わせばできる
違うよ!全然違うよ(・A・)!
ソフトウェアの生産は車の作業工程に置いて、設計部分にあたる
コードが工業製品と勘違いされているために、「ソフトウェアの生産」は車の生産ラインのように扱われることがある。
しかし、ソフトウェアは本質的には情報なので、流れ作業は0に等しく、生産ラインのような作業はない。実は、ソフトウェアの生産は車の作業工程でいう「設計 = デザイン」の部分にあたる。車を設計する時には、原寸大の粘度を削って車の形にする。そして、それが美しいとか議論されて最終的なデザインに落ちる。
自動車業界で新車というと年に10台くらいしか出てこないのに、車のデザインと同じくらいクリエイティブで大変なソフトウェアは毎年大量にでてくる。これは、ソフトウェアが「ものづくり」として理解されてしまっている部分に原因があり、このギャップが不幸を生んでしまっている。例えば、コードの設計部分が軽視されるものそのためである。
本来、ソフトウェアの生産は設計なので、次の様な性質をもっている。
- 職人芸
- そこから生まれるソフトウェアは一品もの
- ソフトウェアにはよしあしがある
コード != 芸術
コードは、美術等の芸術ともまた違う。見るだけで楽しんだりするものではない。
- 実用的であってナンボ
- 用の美を持つ
コードは読み物でもある
コードは人がコンピュータに「何をすればいいか」を教えるコミュニケーションの道具だが、人同士のコミュニケーションにも使われる。人がコードを読むこともとても大切なこと。
- 教材としてのコード(Twitter にpost するとはどういうことなのか)
例えば、Twitter にpost するということを知りたければ、その動作をするコードを読めばいい。コンピュータに仕事をやらせるには、何をすればいいかを完璧に教えなければならず、それがコード。なので、コードには曖昧性がない。
仮に、「Twitter にpost する仕様書」みたいなものがあったとしても、その仕様書を読むよりTwitter にpost するコードを読んだ方が、「Twitter にpost するということ」を完璧に理解するこができる。
- コードは知識の宝庫
どうやってスケーラビリティを持たせるか等、そういうことがコードには書いてある。コードを読むことで、その知識を得ることができる。
美しいコードとは
パワーを持つコード
- パワーを持つとは
コードを見ていると、「その発想はなかった!そんな風にできるのか!?」と感動することがある。コードには人を感動させるパワーがある。
- パワーの源
そのパワーを生み出しているのはアルゴリズムである。
例えば、ソフトに重い部分が見つかれば、大抵のプログラマはボトルネック部分を見つけた後、変数の数を減らしたり小手先の修正をする。一方、優れたプログラマはアルゴリズムとデータ構造自体を見直す。
小手先の修正だと、せいぜい20%くらしか改善できない速度が、アルゴリズム自体を変えることで時に1000倍の改善ができたりする。
別例として、ruby の文字列処理がある。
最初、ruby で扱える文字コードはSJIS, EUC-JP の2種類だった。UTF-8対応はまつもとさん自身、ほぼ無理なんじゃないかと思っていて手をつけないでいた。しかし、吉田さんという人がそんなに手間をかけずにUTF-8対応させることができるパッチをメールで送って来た。しかも、速度的にも問題ないコードだった。
最初は無理だと思っていても、実際そのコードを読むと「なるほど」となる。「きっと無理だろう」と書く前から思っちゃうのを打破するパワーがコードにはある。
効率の美
ここでは「生産性」と「簡潔さ」に関して、ポールグレアムのSuccinctness is Power(簡潔さは力なり)というエッセイを元に話をされていました。
- プログラミング言語の進化とは
このエッセイによると、プログラミング言語の進化は「いかに人の意図を簡潔に記述できるか」という方向に向かって来たという。
「人月の神話」にある法則の一つに、Brooks の「生産性不変の法則」とうものがある。それは、ある1人のプログラマが一日に書けるコードの量は決まっていて、かつ、それはどんな言語を使うかには依存しないというもの。つまり、FORTRAN で書いてもruby で書いても同じ行数を書くということ。
しかし、実際にはFortran の500行とruby の500行ではできることの量が大幅に違う。これはライブラリや言語の設計の違いによるもの。使う言語によって生産性が高まったということは、言語は、「いかに簡潔に意図を記述できるか」という方向に進化しているということを裏付ける。
- 言語開発者が意識する簡潔さ
言語開発者が言語を設計する時には、「実行可能疑似言語」という形を目指している。
疑似言語とは、アルゴリズムの解説書にでてくるような、実際には動かないけどアルゴリズムの本質だけを記述するために使われているもの。何故ソースで示さないかというと、ソースだと言語特有の「おまじない」が多く、本質的に伝えたいアルゴリズムの部分が埋まってしまうからだという。
それなら、「その疑似言語が動けばいいじゃん!」というのが「実行可能疑似言語」の考えで、それはコンピュータとの間の約束のための「おまじない」を書かず、コンピュータに何をやらせたいかという本質的なことだけを記述できる。
HelloWorld をするとき、例えばJava だと「public class ...main(String args[])...」とかも書かなければいけない。
一方、Ruby では「print "Hello World\n"」だけで良い。「Hello World という文字を出したい」ということを簡潔に表現できていて、美しいコードと言える。(もちろんJava がこのように書かなければならないのには、型があった方が良いといったような意図があるからである)
DRY
DRY なコードは美しい。例えば、DB のユーザテーブルを扱うクラスを作りたいというとき、ActiveRecord を使えば以下のように書くことができる。
class User < ActiveRecord::Base end
ここにはテーブルがどんなカラムを持つかすら書かれていない。それはテーブルのスキーマだけが管理している。なので、スキーマが変更になっても、このクラスは一切変更しなくて良い。
シンプルは美しいか(Ruby 自体とRuby を使って書いたコードの簡潔さ)
美しいコードにある誤解の一つとして、何でもかんでもシンプルにすれば良い、シンプルじゃなければいけないという誤解がある。
そもそも、シンプルとは何なんなのか。
- 簡潔さの罠
全てのコードをシンプルに保つのは実は不可能に近い。なぜならば、コードが扱うのは現実世界の問題であり、現実世界はとても複雑だから。よって、ソフトウェアが複雑になるのは避けられない問題で、これは認めなければならない。それでもシンプルにするとどこかにシワよせが来る。
- 複雑さ、簡潔さをどこに持たせるか
全てのコードをシンプルに保つのは難しいという話の通り、例えばRuby ではとても泥臭いことをやっている。しかし、そのおかげで、Ruby で記述されたプログラムを簡潔に保つことができるようになっている。
シンプルな言語でソフトウェアを作ればソフトが複雑になり、逆にソフトをシンプルに記述するためには言語がその複雑さを負う必要がある。
- 理想は水鳥のごとく
Ruby を使ったコーディングでは、見える部分では優雅に見えるけど、見えない部分では泥臭いことをやっている。
これを「怠惰のための勤勉」とまつもとさんは表していた。手抜きをしては美しいコードを書くことは当然できない。でも、苦労を見せびらかす(表面に見えるようにする)のは粋じゃない。まさに水鳥。
「全てをシンプルにすること = 美しい」ということではない。Ruby が簡潔な表現ができると評価されるのは、Ruby 自身が複雑さを引き受けているからでもある。
思考の流れにあっているコード
「○○を〜して、〜して、〜する」のように、人の思考は左から流れている。そのように表現されているコードは美しい。
- プレゼン資料の例を忘れたので自作
'ruby emacs'.split.map{|q| "title LIKE '%" + quote(q) + "'%" }.join(' AND ')
外面の美しさ
コード(= ソフトウェア)には外面的な美しさもある。ここでは、「人にフォーカスしたソフトウェアは美しい」という話がありました。人を考慮した優しいコードは美しい。
- 使うことで使っている人を進化させるようなソフトウェア
Excel の表を見ながら電卓叩いている人を見ると、上手く最適化されていない気がする(その人にとってExcel の習得コストが高い*1)。
マスターするのは大変だけど、マスターすると進化につながるようなソフトが美しい。まつもとさんは自分のマシンのローマ字のキー配列をいじるコードを書いた。最初3日間くらいはまともに文字が打てなかったけど、今はいくら大量に文字をうっても腱鞘炎にならない。(怠惰のための勤勉)
総じて、美しいコードとは
ここまでの話をまとめると、「美しいコードとは、理解に基づいたコード」ということになる。
- 人への理解(外面の美)
- どのように書くと読みやすいのか
- どんな風に使えると人は嬉しいのか
- これが唯一の正解というものはない
- 機械への理解(内面の美)
- どんなアルゴリズムを使うといいのか
- 外面の美ほど価値観は変化しない
美しいコードを書けるようになるために
アーティストとしての自覚
前述の通り、コードは工業製品ではなく、一品ものの「作品」。つまり、「プログラマ = アーティスト」。作品を作っているんだというこの自覚を持つことがまず重要。決してプログラマは作業員ではない。
自覚が重要な事例として「石を切っている男」の話をされていた。
3人石工に「何をしているの?」と聞いたことろ、1人目は「石を切っているんだ」と答え、2人目は「お金を得るために石を切っている」と言った。3人目は「神殿を作っているんですよ。神様と出会うことができる素晴らしい場所を作るお手伝いをしているんです」と答えた。同じことをするにも、自覚によってプログラミングは作品を作っているんだと誇りを持つことができる。
アーティストとして大切なこと
- 創造性がある
他の人と同じことをするのは楽だが、それでは意味がない。自分で考えて創造しなくてはいけない。「無理だー」とか思うんじゃなく、「もしかしたらできるんじゃない?」と思って問い続けるのが必要。
- 自発的であるか
プログラミングにはセンスが必要だと言われることがある。現実的にそれは認めないといけないことだと思う。しかし、それ以上に重要なのは、この自発性。
アーティストとして自覚があれば勝手に学んでいくし、継続することもできる。作品を作りたいという思いがモチベーションになっている。
アーティスティックなプログラマ
アーティスティックに振る舞えと言っても、実際の仕事には「納期」、「お客さん」、「チーム」等があり、「俺はアーティストだからそんなことはできません」と言うことはできない。
しかし、他の業界の中にはアーティスティックな活動をしていても、きちんと仕事となっている職種がある。そういうところからもっと学ぶことがある。プログラマだけがアーティスティックに仕事をすることができないなんてことはない。
繰り返しになるが、まずは自分だけでも自分はアーティストだと自覚することが大切。決して使われるだけの作業員になってはいけない。まだ周りに理解してくれる人がいなくても、「心の中のアーティストは誰にも止められない」
まとめ
- コードは美しい
- コードはアート
- プログラマはアーティスト
感想
とても素晴らしい内容でした。やっぱりどの世界でも一流の人は自分の考えをしっかり持っていて話が面白い。今回の話の中で印象に残った部分がありました。
今30〜40くらいのプログラマの話です。その人達は昔「マイコンBasic マガジン」という本を買い、そこに書いてあるコードを自分のマシンで打って動かしていたと言います。でも、しっかり写したつもりでも何故か動かない。そこでまた雑誌のコードを読みながらデバッグしてBasic を学んでいったという話でした。
今はこんなことをしている人はほとんどいないと思います。ソースはWeb で見られるし、DL してコンパイルすれば使えるようになる。自分で写経しなければならないという状況は減ったと思います。しかし、それがコードリーディングしないプログラマを生み出していて、それが美しくないコードを生む原因にもなっているんじゃないかなと感じました。
本を読まなくなった若い人の文章力が低下しているという話も良く聞きますが、コードを読まなくなったプログラマにも同じことが言えるなと、自戒の念を込めてあらためて感じました。
本を読まないで作家になれるわけもなく、毎日楽器を触っていないのに一流の音楽家になれるわけもなく、毎日コードを読み、勉強している人が一流のプログラマになっていくんだと改めて感じました。
講演をして下さったまつもとさん、セミナーを主催して下さったウェブキャリアさん、ジェイブレインさんありがとうございました!
*1:講演された内容と違っていたので修正致しました。id:bak_a_mono さんありがとうございます!