By plushoff under CC BY-NC
山口さんから、「Java開発者のための関数プログラミング」の電子献本をいただきました。ありがとうございます。電子書籍便利ですね。アメリカにいても日本語の本が手に入る!しかも、すごいこなれた日本語になっているし、注釈もばっちりついて読みやすいです。仕事のできる男の風格を感じます。
- 本人のブログ: http://ymotongpoo.hatenablog.com/entry/20120621/1340233739
- オライリーの書籍ページ: http://www.oreilly.co.jp/books/9784873115405/
この本を楽しく読んでいたところ、山口さんから別の面白いリンクを教えてもらいました。
- Why OO Sucks (なぜオブジェクト指向はクソなのか)
Erlangの開発者のJoe Armstrongの記事です。本当はこっちのycombinatorの議論(http://news.ycombinator.com/item?id=4245737)も全部目を通したいところだけど、まだそこまでは読めてません。
中身に関しては同意できるところもあるし、文脈依存だなぁと思うところもありますが、最後の「なぜオブジェクト指向が人気となったか?」という点は「Java開発者のための関数プログラミング」とクロスオーバーすることもあり、興味を惹かれました。まぁ、こちらの中身に関しても100%同意ではないので、僕なりの考えなりをまとめたいと思います。
関数型言語系の人は当然そちらの方が優れている、書きやすいと言うことを言います。パフォーマンスも良く、メンテナンス性も高く、コードも短いとか。僕もどちらかというと関数型っぽい環境でコードを書いたことがある(お試しでErlangでProject Eulerとか、今は亡きJustSystemのxfyでプロトタイプのアプリケーションを作ったり)のでイメージは付きますが、TIOBEスコアとかではOO系が主流だし、今の言語やパラダイムで物足りなさを感じている人以外を説得するには、強く主張すればするほど逆効果だよな、といつも思っています。Erlangはずっと前から(前職から)仕事で使ってみたいと思っているけど、自分もなかなか他人を説得できないですしね。
「言語の優劣と、流行したかどうかは直接は関係ない」「タイミングが命」というのが僕の考えです。そうでなければ今ごろ「JavaScriptなんてダセーよなー」「家帰ってSmalltalk/Lispやろー」(湯川専務のCM風に)という会話を中学生とかがしているはずですから。異論や反論もいろいろあると思いますが、僕なりにオブジェクト指向が流行ったとおもわれる要因をまとめてみました。
OOはなぜ流行ったのか?
GUIとオブジェクト指向
C++が使われ始めていた時代(1990年代)は、C言語もたくさん使われていました。その時代はコマンドラインの世界からGUIへとシフトしつつあり、オブジェクト指向のC++は輝いて見えました。
Cの世界からC++の世界に行けば、プリミティブなWindows APIではなく、MFCのような高度なGUIライブラリが利用できたからです。プリミティブなAPIを叩いた場合、ウインドウを表示するのにも大量のコードが必要でした。MFC以外にも、DelphiやC++ Builderなどのオブジェクト指向で作られた先進的なGUIライブラリがいくつもありました。また、ぽちぽち貼り付けてちょっとコードを書くだけでアプリケーションが書けることで大流行したVisual Basicもオブジェクト指向を元にしていました。
C言語でもGUIは作れました。Windows APIや、XLibがそうです。低層なC言語と、高水準なオブジェクト指向みたいなヒエラルキーを強く感じました。
もちろん、関数型でもGUIは作れるでしょう。前述のxfyがそうですし、今でもwxErlangとかがあります。ですが、この時代はどの雑誌を見ても、本を見ても、高度なライブラリは「クラスライブラリ」と呼ばれて、オブジェクト指向でデザインされていました。
アジャイルとネットとオブジェクト指向
2000年前後になると、C++やVisual Basic、Delphiもたくさん使われていました。その時代は世界がインターネットやアジャイルへとシフトしつつあり、オブジェクト指向のJavaが輝いて見えました。
C++の世界からJavaの世界に行けば、環境ごとのTipsを追いかけたり、IBM製の巨大ライブラリをがんばってインストールする必要もなく、スムーズにスタートできました。当時はTurbo LinuxやVine Linuxなど、日本語が使えるLinuxのデスクトップ環境のインストールも簡単になり、業務でLinuxという話題が出始めたり、iモードアプリなども出てきたり、世界が多様になってきました。
そしてアジャイルです。本家XPのスタート(C3プロジェクト)はSmalltalkでしたが、日本ではJavaとともに広まりました。JUnitはCppUnitなどよりも簡単でした。リファクタリング本ではJavaのコードを綺麗にする方法がたくさん紹介されました。デザインパターン本も、結城浩さんのJava版の方が売れていたらしいです(伝聞なんで確証はないですが)。Java系の雑誌ではこの手の「新しい」話題があふれていました。この時代、アジャイルはとても輝いて見えました。そのアジャイルの世界に入るには、事実上オブジェクト指向というチケットが必要と当然のようにみな思っていました。
C++はどちらかというと、ライブラリ設計者の方に向かって発展して機能を増やしていました。Javaはその逆側のスタンスを取り、標準ライブラリを大量にそろえ、フレームワークを用意し、「ライブラリを使う」立場の人が大多数である、というスタンスで発展しました。
もちろん、関数型でもテスト駆動開発はできます。副作用がない分やりやすいでしょう。JUnitなどのフレームワークは、「独立性の高いテスト」を実現するための枠組みで、オブジェクト指向の欠点を克服するものとなっています。privateをどうテストするのか?といったこともアジャイルコミュニティではよく議論されていました。
ウェブアプリとLLとオブジェクト指向
2005年前後になると、Javaもたくさん使われていましたが、Lightweight Languageというものがかなりの勢いで広まってきました。その中でも、日本で多くの雇用を生み出したのが、PerlとPHPとRubyです。 簡単なテキスト処理のための言語は古くから良く使われてきました。AWKは僕もアマチュア無線のログの処理で使ったことがあります。2000年ごろにはCGIと関連した大量のPerl本が並んでいました。Cマガジンの連載で、YukiWikiを見て「ウェブの世界はこんな面白いものがあるのかー」と思ったものです。インターネットのプロバイダと契約すると10MBぐらいのウェブサイトのスペースをもらうことができ、CGIとSSIを使えば動的なサイトも作れました。ただ、後者は提供されないところも多く、また掲示板スクリプトなどがフリーで提供されたこともあり、CGIが多く利用されました。 僕はあまり情報を追いかけてなかったのですが、CGIの延長で、RDBを使った本格的なウェブ開発でPHPが多く使われるようになったと思います。PHPは他の言語を知っている人からはよく悪く言われます。僕は使ったことがないので具体的に悪いポイントは言えないのですが、気軽にデータベースを利用したウェブアプリケーションを開発することができますし、ドキュメントを見ると、静止画の動的生成や、Flashのムービーを差し込むための機能なんかもあります。「こういうサイトを作りたい」と思うデザイナーの人からみると、実に魅力的に見えるとおもいます。LL界のVisual Basicと言えると思います。
Rubyも昔から根強い人気がありましたが、Ruby on Railsが出てからは、他の言語から乗り換えというケースが増えたように思えます。新聞やテレビの媒体で「ルビー」という文字が出た!「Matz江市!」と話題になることも増えてきました。Rubyはもちろんのこと、他のLLも基本的にはオブジェクト指向のパラダイムを当然のように取り込んでいます。
Javaでもウェブアプリケーションの開発はできますしし、かつて業務向けはJavaの方が話題の中心でした。Javaはクラス指向をさらに推し進めて、コンポーネント方面に舵を切りましたが、定形コードが大量に増えたり、Javaのフレームワークを使うとスタックトレースが異常に長い!という画像が出回ったりしました。今ではScalaなどを除いて、新規開発でPure Javaでウェブのシステムを作ることが話題になることはあまりなく、最近は他の言語のためのJITの賢い実行環境か、AndroidとJenkinsとHadoopのための実行環境扱いされているフシがあります。
JavaScriptとオブジェクト指向
ここ数年は、クライアント側もサーバ側もどこもかしこもJavaScriptが話題になっています。
ウェブブラウザのクライアントのプログラミングというと、JavaScript以外にも、いろんな言語が使えるSilverlightや、FlashのActionScriptもありますが、スマートフォンの広まりもあってJavaScriptが事実上標準となっています。DHTMLと言われていた暗黒時代から返り咲いたきっかけはprototype.jsでしょう。歴史上はGoogle Mapがきっかけと言われることも多いですが、実際にエンジニアが手にとってコードをたくさん書くようになったのはprototype.jsからかなと思っています。prototype.jsは「オブジェクト指向言語」としてのJavaScriptの魅力を補完するものでした。その後はその地位をjQueryに明け渡しましたが、Backbone.jsなど、JavaScript補完計画はまだ続いています。
HTML5はここ最近のホットな話題でしょう。分裂話もあってまだまだ話題を提供し続けてくれそうです。ただ、HTML 5という名前ですが、CSS3以外の90%の話題はJavaScriptです。APIは基本的にオブジェクト指向路線です。また、ECMA Script 5など、JavaScript自体のバージョンアップも話題になるようになりました。サーバサイドのJavaScriptも、V8エンジンのオープンソース実装やnode.jsとともに広まっています。
流行の構造
オブジェクト指向が広まって普遍化していくステップを考えると、次のような構造が見えてきます。
今いる世界と、次の世界があります。この世界の間は不気味の谷とか色々マーケティング用語で説明されたりもするものだと思います。次の世界の中には最初からヒエラルキーがあり、「すごい新しい世界」と「しょぼい新しい世界」があります。GUIの時代には「ウィンドウズ上の新しいかっこいい部品をいっぱい使って、すごいGUIを作ろう」という流れがありました。「こっちの言語ではこんなGUIが作れるぞ」「こっちのフレームワークではこんなことができるぞ」というのが話題の中心になりました。アジャイルの時代は、「XPのプラクティスを何個実践できるのか?」というのが話題でした。なかなか周りの環境を動かすに至らず、開発者単独でできるユニットテストとリファクタリング止まりという人も多かったのですが、「仕事でアジャイルしている」人は本当にヒーローでした。
このような構造ができると、人は次の世界に渡るコストよりも、次の世界でどう上に上がっていくかということに注目して、次の世界に渡るコストが気にならなくなります。子供たちの流行もそうですよね。ミニ四駆の時代はいかに速く走るかで、持っていて当然という感じでした。ビックリマンやムシキングやラブアンドベリーも、どれだけすごいシール/カードを持っているかが大事で、ただ持っているか持っていないかが話題になることはありません。大人の例を挙げる場合iPhoneも「どれぐらい早く買うか」で話題になりましたよね?
関数型言語が流行るために必要なことは?
関数型言語が流行るためにも、「関数型言語を知っていて当然。あとはそれでどんなことをするのか?」というのが話題になるのが必要だと思います。「副作用がないよ」とか「効率が良いよ」ではあまり人が動かないですよね。「再利用性が高い」と同じにおいがしますし、学習コストがどのぐらいでペイできるかどうかのヒントが全然ないですからね。僕の経験上「10時間の準備をすれば、毎日の作業が30分短縮されて、2ヶ月で元が取れて後はハッピーだよ」というような、例えトータルがプラスでも事前にちょっと大きめなコストがかかるような提案はうるさがられることが多いです。
そのためには、関数型言語でしかできないことなんかがもっといっぱいあると良いかな、と。OCamlはその高速性から金融系では多く使われているとのこと。また、Erlangは分散処理を書くためのDSLとして一定の地位を獲得しています。個人的には、シェーダーも含めて、シームレスにグラフィックスパイプラインやら、物理シミュレーションやらのゲームコードが関数型言語でスマートに記述できるようなツールが出て欲しいなぁと思っているところです。関数型はパーサーを書くのも得意だと思いますので(Rubyみたいに正規表現がややこしくて、文脈依存が多いの以外)、PyPy Toolchainみたいな、言語処理系フレームワーク(JIT付き)みたいなのも関数型言語でできたらいいな、と思います。
「Java開発者のための関数プログラミング」では、そこのところに「並列処理」を持ってきています。そして、関数型言語がどういうツールを開発者に提供しているのかをコードや説明などを交えながら丁寧に紹介してくれています。僕も初めてモナドと遅延評価の関係などがわかりました。「とにかく手を動かしていれば、そのうち真理に気づく」みたいな日本的なトレーニングが好きな人は置いといて、まずは外枠を理解して、着実にステップアップしたい人にオススメです。「構造化言語だけど構造化しないで1関数2000行」とか「Javaでも全部staticでC的に書いちゃう」笑い話もありますし、「関数型言語を使えば関数型が自然に理解できる」ということはないと思います。むしろ、過去の経験に引きづられてしまうことも多いと思います。この書籍は「関数型じゃない」パラダイムの人向けに新しい世界の要素を1つ1つ紹介してくれています。実際、この書籍のサンプルどおりにJavaで関数型のプログラムをバリバリ書こうという人は少数だと思いますが、他の言語を勉強する時の副読本として、他のパラダイムの癖を抜くためにとても有効な本だと思います。
言語をDISるのはやめよう
ちょっと別件になりますが、最近思うのが、言語をDISるのはお里が知れるなぁ、ということです。自分がよく知っている言語ほど不満な点がきちんと分かるのはあります。昔DDJという雑誌でみた、エンジニアのスキルを見抜く面談のテクニックで「C++を改善するとしたらどこですか?」というのがありました。欠点を知り、さらにどうすれば克服できるかまで理解できる人はその言語の経験も十分にあり、理解力も十分にあるということです。
でも、最近よく見る言語DISりは「俺凄いだろう」的な雰囲気を匂わせている感じが多い気がします。特に、他の言語を持ち上げるための他の言語のDISりは「お前らの使っている言語はしょぼい、すごい言語を使っている俺すごい」的な感じですよね。自分では自分は凄いと思うのに周りから理解されておらず、自己充足感を満たしたい人のように見えて、なんかかわいそうに見えてきます。「これ勉強したいんだけど、どうすればいい?」という質問に対して、相手のレベルや目的を考慮せずに「いいからこれをよめ」「これを読まないのはありえない」みたいに言っちゃうのも、往々にして似たようなのを感じますが、まぁ話が変わってしまうのでまたの機会に。
その点「Java開発者のための関数プログラミング」はきちんと相手(オブジェクト指向な人)のために書かれた文章です。Javaでできない限界をきちんと考慮した上で、「外の世界にはこういうものがあるよ」「興味があれば使ってみよう」と丁寧に紹介しています。人に新しいものを紹介する時には、こういう姿勢を心がけたいです。