2012-02-29

言語はどれも同じじゃない

僕も以前は、言語には得意不得意、向き不向きはあっても優劣はないという立場をとっていました。
でも、はっきり言います。それは間違いでした。ごめんなさい。

例えば、徒歩と自動車で移動する場合それぞれを比べた場合、
  • ある程度以上距離がある場合の速度では、自動車のほうが徒歩に勝る
  • 旋回性能では、徒歩のほうが自動車に勝る
  • あまり距離があると、徒歩では現実的な時間内に到着できない可能性がある
  • 数メートル以内の極短距離では、わざわざ自動車に乗るよりも徒歩のほうが速い
  • たとえ自動車がエコカーであったとしても、エコ性能で徒歩に勝ることは決してない
のように、いろいろな側面で得手不得手があります。
でも、このような向き不向きのほとんどは、境界条件的な状況でのみ発生するものです。
どちらかを選択する必要があり、また一旦選択したあとで変更するには多少なりともコストがかかるという場合、このような向き不向きが選択に影響する状況はあまり多くありません。

ありていにいえば、「徒歩と自動車のどっちで移動したいですか?」ときかれたら、普通どっちと答えるかってことです。


僕は普段、電車で1時間をちょっと切るくらいの距離を通勤しています。
自動車で移動したら、まぁだいたい1時間半くらいでしょう。
でも徒歩だったら...ちょっと待ってください。GoogleMapで調べてみます。
えっと...2時間47分でした。しかも、今のGoogleMapでは、徒歩のルート検索はベータ版で、歩道のない道が含まれてる可能性があるんだそうです。場合によっては、もっとずっとかかるかもしれないわけです。
毎日行きと帰りに3時間近くかけるなんて、まったく現実的じゃないですよね。

言語も同様です。 あらゆる言語はチューリング等価であるなんて事実には、なんの価値もありません。
ある言語で実装できるものなら、他の言語でも必ず実装できるでしょう。でも、それには途方もない時間がかかるかもしれません。


この点に関して、ポール・グレアム氏は非常に率直です。
ハッカーと画家 で、どれが一番かを確実に決めるのは難しいが、言語には明らかに差があると主張しています。

僕は、言語のパワーは、同じ事をどれだけ少ない時間で実装できるかで決まると考えています。
もちろん、言語には実行速度やリソース効率など、他の側面で見たパワーもあります。
しかし、ムーアの法則によって、そういった側面でのアドバンテージは、急速に意味を失っていくことがわかっています。
コンピュータのリソースは、すでに相当安価であり、今後も年々安価になっていくのに対して、我々プログラマの時間は常に貴重です。

そして、こちらは今後も安価になっていく見込みはありません。
したがって、言語には、コンピュータリソースに対する効率より、プログラマ時間に対する効率が求められるべきです。

コードの世界7つの言語 7つの世界 から受ける印象では、まつもとゆきひろ氏も同じような意見をお持ちだと思います。...たぶん。
違ってたらすいません。 実装効率という視点で考えた場合、例えばアセンブラとRubyでは明らかに大きな違いがあります。
これに異論を唱えることは、かなり難しいと思います。
COBOLとJavaでも、やはり違いは明らかです。
Objective-Cも、Perlも、JavaScriptも、Pythonも、Groovyも、Lispも含めた全ての言語が、このアセンブラとRubyを結ぶ直線上のどこかに位置します。
もちろん、あなたが好きななんとか言語もです。
問題は、それがアセンブラ寄りにあるか、Ruby寄りにあるかです。
ひょっとしたら、Rubyのさらに先の方にあるかもしれませんね。

どの言語がどこに位置するかを決める単純な方法は、ある課題をそれぞれの言語で実装した時の、記述量の少なさとわかりやすさです。
記述しなければならない量が少なければ、それを書くのにかかる時間も少なくなるのは、当然ですね。
でも「わかりやすさ」なんていうと、主観的で観念的なもののように響いて、指標としては非常に頼りなく聞こえます。
しかし、実装効率を考える場合、わかりやすさは非常に重要です。

僕たちは、コードを書くことよりも読むことが多いからです。
人のコードをたくさん読みなさいとか、新規開発よりも既存システムの変更の仕事のほうが多いとか、そういうことを言ってるのではありません。

一旦書いたら、コードはその瞬間から繰り返し読まれるものになります。
僕たちは、次のワードを書くために、直前に書いたワードを見ます。
次の行を書くために直前の数行のコードを見て、次の関数を書くときにはその関数を呼び出す関数を見直します。
そして次の日には、新たなコードを書くために、前の日のコードを見返します。
全くどのコードも読むことなくプログラムを書くことなんて、ほとんどないでしょう。

だから、読みやすさは実装スピードに大きく影響します。


ところで、その言語の熟練者と初心者では、わかりやすさ、わかりにくさを感じる点は全く違います。
初心者が注目するのは、多くの場合インデントが揃っているかとか、ブロック開始のカッコが行末と行頭のどちらにあるかとか、それらが統一されているかとかいう、シンタックスの表象的な部分です。
または、自分がより習熟している他の言語との類似点が、多いか少ないかとか。
それに対して、熟練者はモジュールや関数の抽象度や対称性、結合度、デザインのシンプルさ、適切なアルゴリズムの選択、イディオムやパターンの表現に注目します。

初心者は、自分が慣れ親しんだ言語には全くなかった概念だとか、そのコミュニティになかったイディオムについては、わかりにくいと感じて敬遠する傾向があります。
その場合、それが実際に効果的であるかどうかは別問題だったりします。

もちろん、インデントが不揃いなのは誰にとっても読みにくいですが、より重要なのは初心者が見るような表面的なことでなく、熟練者が注目する部分であることは確かです。
もし逆の選択(つまり、どんな新人でもすぐ理解できるようなコードとか)をしてしまったら、あなたのアプリケーションは技術的なアドバンテージを失い、長く生き残ることは難しいでしょう。


記述量をできるだけ少なくするなら、例えば
  • 変数名や関数名をできるだけ切り詰める。可能なら1文字
  • スペースやインデント、余分な改行を排除する
  • 可能なかぎり、オブジェクトよりプリミティブ型を使う。
のような極端なやりかたも考えられます。
しかし、この方法では、わかりやすさという点から見ると決して良い点はとれませんね。


わかりやすさを保ちつつ記述量を減らすような言語の特徴には、以下のようなものがあります。
  • 抽象度
  • 動的型付け
  • メタプログラミング
  • クロージャ
  • 関数型

これらすべてのトピックの内容について、ひとつのエントリで書き切ることはとてもできそうにないので、今回はここまでで終わりにします。
興味がある方は、ハッカーと画家コードの世界を読むか、ググってみてください。

機会があったら、それぞれについてまた書くかもしれません。

0 件のコメント:

コメントを投稿

Related Posts Plugin for WordPress, Blogger...