プログラミング言語の使いわけ

私は色んなプログラミング言語を触るのが病的*1に好きで、どの言語をどういう場面で使うのが良いのか凄く興味があります。

そこで、今の私の知識範囲でのそれぞれのプログラミング言語の使いどころを(自分用の整理もかねて)書いてみます。

C/C++ - C=OSやミドルウェアC++=効率化のための再実装

安直に「メモリとスピードが第一優先のとき」と思いたいところですが、同等程度のスピードでもっといい言語はいっぱいあります。計算集約的ならJuliaとか、オブジェクト指向で組むようなソフトならD言語とか。なのでまずC言語は、Swigみたいのを使って他の言語の拡張ライブラリを書いたり、システムコールを使ってOSやミドルウェアを書くときじゃないかと思います。C++はテンプレートを駆使したりして効率を維持しながら抽象度の高いコーディングをするような場面がしっくり来ると思います。既に他の言語で実装したソフトウェアのパフォーマンスを改善するためにC++で書き直すときとかがピッタリだと思います。

D - 仕様変更に強いC/C++

D言語はテンプレートのようなC++的な効率維持を持たせつつmixinなどのオブジェクト指向実践テクの面を合わせた言語だと思います。Dを使うのはメモリに読み込んで色々複雑な事をやるような普通だったらC/C++を使う場面で、コードの見通しを保ちながら抽象度を上げたいときじゃないでしょうか。つまり、Cで書いちゃうと要件が変わったときに書き直しが大変なのでもう少し変更が楽な言語が欲しいときにピッタリなんじゃないでしょうか。

Objective-C - Appleプラットフォーム

iOSMAC用のアプリを作るときですね。他でそれがピッタリとなるような用途は無いと思います。

Perl - シェルの機能強化

PerlはWebアプリからバッチ処理まで何でも使えますが、言語の種類が豊富になった現在ではPerlを使う事が最もしっくり来る場面というのは少なくなっているかもしれません。シェルからコマンドとして使うようなソフト、リダイレクトやパイプを扱うような処理が一番の使いどころな気がします。Perlはもともとの出自がshやC言語sed/awkなどの発展形なので、その部分では後発のスクリプト言語より優っているように思います。Perlオブジェクト指向はちょっとハッキング的すぎるかなと。

Ruby - ドメイン特化処理

RubyはなんといってもRailsでしょう。Webアプリケーションを最も速く作れるフレームワークRailsだと思います。「テキスト処理がメインでドメイン知識をいろいろと仕込んでいくようなアプリ」がぴったりだと思います。PythonRubyとくらべると関数型の色が少しあるように思いますが、Rubyは純粋にオブジェクト指向を追求しているので、処理の一般化がしにくく差分を積み重ねながら組んでいくようなドメイン特化型のアプリにより適していると思います。

Python - データの加工

Pythonはいま最も「汎用性」が高い言語じゃ無いかと思います。特に理由がなければデフォルトでPythonというのはアリだと思います。その中で、Pythonを使うのが最もしっくりくるのは「データの加工、データ分析における前処理・後処理」じゃないかと思います。テキストや画像、音声、それらの入出力、ネットワーク通信といった機能がそろっています。それとデータ分析本体のアルゴリズムもScipyなどの便利なライブラリがありますが、それはたぶんもともとPythonが前処理と後処理に秀でていたからそういう分析本体の機能がどんどん追加されていったのであって、元々の強みは「加工」なんじゃないかと思います。

PHP - コモディティなWebアプリ

実は使った事が無いので分からないのですが、Webアプリケーションの開発でコモディティなカスタム開発にはぴったりなんじゃないでしょうか。

Javascript - リアルタイムWeb

JavascriptHTML5を使ったリッチなクライアントアプリケーションはもちろんですが、強力なV8エンジンとNode.jsの登場のおかげで効率的なサーバサイドの処理にも使えます。そうした特長を一言で言えば「リアルタイムWeb」でしょう。DBアクセスがメインのアプリケーションはRailsDjangoを使えばjavascriptの部分はそれほど書かなくてもすむ事が多いですが、HTML5ajax、さらにC10K問題への対処を要する大量同時アクセスが生じるリアルタイムWebアプリケーションにおいてはJavascriptはピッタリです。また、バッチ処理的に使う場面でも、Webをクローリングしたり各種APIマッシュアップしてデータを統合するなど、時間経過に伴ってデータの更新ももとめられるような準リアルタイム的な要件にも他の言語より優位性を発揮すると思います。

R - データマイニング

最近はやりのR言語。統計分析やデータマイニングにピッタリです。Python や他のツールを使う場合と比べてワンストップで前処理・分析・可視化が出来るので前処理がなんとか終わってCSVやリレーショナルDBまでデータ準備が出来たあとは強いです。

Julia - アルゴリズム実験

最近出たばっかりの言語ですが、FORTRANMatlabのように科学技術計算のアルゴリズムをゼロから実装して効率よく計算させたい場面で力を発揮しそうです。ただ、大抵のアルゴリズムは様々な言語でライブラリが存在するため、Juliaを積極的に使う場面はとくにアルゴリズムの評価をしたいときじゃないでしょうか。ただ、アルゴリズムの研究をする人たちは今はまだC++PythonJavaMatlabを使う事が多いので、Juliaがその立場に立てるのはもう少し先でしょう。

Java - トランザクションの保証

Javaは業務システムでよく使われています。技術者の数も多いですが、たぶんそれはWebでPHPプログラマが多いのと同じで業務システム開発の市場規模が大きいからなだけでしょう。言語自体の汎用性の高さ故にエンジニアが多いわけではないと思います。Javaが得意とするのは「トランザクションをきっちりやる」ようなアプリケーションじゃないでしょうか。企業における業務では「後戻り」がなく「約束」がやぶられないことがとても重要です。そういう意味でシステムが落ちずに稼働しつづけることはとても重要です。Javaアプリケーションサーバを使えば一部のアプリケーションにバグがあっても全体としてはちゃんと動き続け、アトミックなトランザクションを再実行することで処理を継続できます。ScalaやGroobyやClojureを使う場合と比べて技術者の数が多いので業務システムのカスタム開発にはピッタリでしょう。

Scala - 高密度なビジネスロジック

ScalaJVM系言語なのでトランザクション処理には強いです。JavaでなくScalaを使う理由はコードの抽象度を高めて複雑な処理を簡潔に書けるようにするためでしょう。スクリプト言語よりも実行効率が求められるハイトランザクションなシステムで特にビジネスロジックが高密度な時にしっくりくるんじゃないでしょうか。またそうしたビジネスロジックを外部からプラガブルにしたりドメイン特化言語(外部DSL)を構築したりする際もしっくり来そうです。

Groovy - 内部DSLフレームワーク

GroovyはRuby的なコンセプトをJVMの枠組みで最適に実装した言語です。積極的にメタプロを使う事が想定されていて内部DSLを作るのに向いていると思います。一番有名なDSLはパッケージ管理&ビルド統合システムのGradleです。Groovyのメタプロを少し覚えればGradleのようなドメイン特化言語を要件に合わせて作る事が出来ると思います。関係者さえ把握出来ていれば良いような処理で、定型タスクとドメイン依存タスクがごちゃごちゃとたくさんあるようなケースに向いていると思います。

Clojure - コードの自動生成

LISPから生まれたJVM言語であるClojureは、もちろん汎用的な言語ですが強みは「コード生成」ではないかと思います。プログラムコードの生成はもちろん、HTMLや数式や音符などのマークアップコードをプログラム的に作るときに向いていると思います。例えば他の言語では通常、HTMLテンプレートエンジンとHTMLスクレイピングライブラリは別物ですが、ClojureではEnliveというライブラリで統合的に両方できます。そのくらい高い抽象度でデータを扱えるので、データ自体が何らかの「動くもの」を表現するような場合でも対応しやすいと思います。HTMLであればDOMツリーをClojure内部に持てば良いし、数式であれば数式相当のデータモデルを、音符ならトラックと音源情報などのモデルを、それぞれ内部に構成してそれらをいじくってコードに戻せばいいわけです。

C# - プロプライエタリシステム

C#を使う場面はJavaScalaと近いと思いますが、.NET Frameworkはより完結度が高いと思います。つまり、オープンソースのライブラリなどを使わずとも元から用意されているものを使えばことたりるくらい部品がそろってます。またVisualStudioがものすごい良く出来ているので開発もそれをメインに使えばかなりの事が出来ます。もちろんCIやレポジトリ・イシュー管理は別のものを組み合わせて使う事も多いと思いますが、開発プロセス多様性を減らす事が出来ます。なので、プロプライエタリなシステムを作る際にはものすごい大きな力を発揮するでしょう。

F# - 高度に自動化したエクセル

F#は.NET Framework上で動くだけあってMS Officeとの親和性は良いです。特にビジネスにおいてデファクトなエクセルは色んな分野で使われており、エクセルを触れる人の数は多いです。そのエクセルユーザのためにエクセル単体では実現しにくいような計算処理をするようなアプリケーションを提供する場合にF#はピッタリでしょう。

Haskell - 処理を動的に組み合わせる

Haskellは純粋関数型という特徴はおなじみですが、ではどんな用途において他の言語より優位性があるのでしょうか。たぶん、Haskellが最もしっくりくるのは、コードを書く前に設計することが難しいような問題、コードを書きながら機能要件を考えるのが適するような問題じゃないかと思います。例えば、ファイナンスの投資戦略とか、医療診断の支援システムとか、そういう「新しい知識」がどんどん追加されるようなドメインで力を発揮すると思います。JavaでもDependency Injectionという方法があってシステム運用時にロジックをあれこれ切り替える事が出来ますが、Haskellの場合はそもそも関数合成を重ねて書いたものを遅延評価して動くので、いわば全ての処理依存を実行時にインジェクションして動くということと普通にやっているようなものです。Clojureはコード生成が得意と上で書きましたが、それに対してHaskellはあらかじめ用意した処理の組み合わせを動的に変えることが得意です。

Erlang - クラスタリングミドルウェア

Erlangアクターモデルを超軽量プロセス(メモリ非共有なのでプロセスといってるだけでスレッドみたいなもの)という実装で使えるようにした言語です。他の言語に対する優位は何でしょう? まずはその軽量プロセスでしょうが、他の言語でもコルーチン形式でリアクティブ処理を書けば同じ事は出来ます。なのでErlangの強みは言語仕様よりもエリクソンで作られた処理系にあるんじゃないかと思います。JVMと比べて同時接続過多な状況でも動作し、コルーチンをサポートするスクリプト言語よりも少ないメモリで動作するので、OSやミドルウェアレベルでの高密度な通信アプリケーションに向くのでしょう。ファイルサーバやメッセージキューといった計算クラスタ内部での(計算本体以外の)システム処理にマッチすると思います。

Prolog - ルールベースの情報処理

Prologエキスパートシステムとして使われます。最近だとProlog由来の制約プログラミングというパラダイムがILogという製品で普及してIBMがそのILogを買収しました。Prologが得意とするのは「ルールの処理」です。ルール集に事例をぶっ込むとルール違反かどうかチェックして違反なら理由を教えてくれたり、何らかの専門的な診断ルールであれば診断結果と診断プロセスを出力したりできます。またILogのような制約論理プログラミングを使うとルールのもとでの最適解を計算することが出来ます。

*1:何か作り始めると「別の言語ならもっと簡単なコードになるんじゃないだろうか。。」という不安がよぎって開発がストップして別の言語で同じ処理を書いてみて「やっぱり一長一短だな」と思って戻る、みたいなことがしょっちゅうあります。