プログラミング言語の特性を理解するためのマトリックス

最近、7年モノのとあるWebサービスアーキテクチャを次の10年戦えるようなそれにどう置き換えていくか、ということを考える仕事をしています。 その中でも、「既存のRuby on Railsで作られたWebアプリケーションを別のプログラミング言語フレームワークで書き換えるとしたら何を使うか」という問は、さまざまなプログラミング言語の特性について改めて考える機会になりました。
本エントリでは、この過程で生まれたプログラミング言語の分類モデルについて紹介したいと思います。

提案モデル

結論から言うと、数あるプログラミング言語の特性を理解するためには、その言語が

  • 静的型付けか、あるいは動的型付けか
  • 言語レベルで並行計算モデルをサポートしているか

という2つの観点で分類すると良いのではないだろうか、と考えています。

型システム

静的型付き言語と動的型付き言語のメリット・デメリットについては既に各所で議論されているので、このエントリでは個別の論点については取り上げません。 私は、どちらか一方が絶対的に優れているとは思っておらず、各々に得意な問題領域があると思っています。
具体的には、

  • 構築したいシステムの規模が大きい
  • 要件が安定している、作りたいものが変わりにくい
  • 関わる開発者の数が多い

ような場合には、静的型付き言語のメリットを享受できると思っています。
例えば、冒頭で述べた「既存のRuby on Railsで作られたWebアプリケーションを別のプログラミング言語フレームワークで書き換える」ようなケースはこちらになりそうです。
逆に、

  • 構築したいシステムの規模が小さい
  • 要件が安定していない、作りたいものが変わりうる
  • 関わる開発者の数が少ない

ような場合には、動的型付き言語のメリットを享受できると思っています。
例えば、「スタートアップで当たるかどうかわからないサービスをできるだけ速く開発する」ようなケースはこちらになりそうです。

ここでは、システムの規模、要件の安定度合い、開発チームの規模という3つの要素を使って問題領域を説明していますが、他にもさまざまな観点があると思います。 どんな観点から説明するにせよ、型システムによってある程度得意な問題領域が規定されることには変わりがないと考え、これを観点の1つとしました。

並行計算モデルのサポート

ご存知の通り、クロック周波数を上げることでCPUの性能を向上させていた時代は(消費電力の増加などが原因で)終わりを告げ、CPUのコア数を増加させることで性能向上を図るマルチコアCPUの時代になりました。
マルチコアが当たり前になった現代において、アクターモデルCSPといったモデルを基にした並行計算のための高水準なインターフェイスを備えていることは、マシンの性能を最大限引き出すために重要であると考えています。 そこで、言語レベルで並行計算モデルをサポートしているかを観点の1つとしました。

4象限マトリックス

以上2つの観点から4象限のマトリックスを作成し、Webアプリケーションのサーバーサイド開発で利用されるプログラミング言語をいくつかマッピングすると次のようになります*1

f:id:Yasaichi:20180113212317p:plain:w460
サーバーサイド開発で利用される言語のマトリックス

いかかでしょうか。 同じ象限に入っている言語にそれほど違和感がないような分類になっていると思います。

この図を作っていて気づいたのは、提案モデルはプログラミング言語の特性だけでなく、その進化の方向を理解するのにも役立ちそうだ、ということです。
例えば、Ruby 3で導入される(予定の)Guildでは、前述したCSPによく似たモデルが用いられています。 これは、ElixirやErlangマッピングされている「動的型付け × 並行計算モデルのサポートあり」の象限へ向かう進化と捉えることができます。 一方で、Python 3.5で導入されたType Hintsは、Javaマッピングされている「静的型付け × 並行計算モデルのサポートなし」の象限へ向かう進化と捉えることができるでしょう。

f:id:Yasaichi:20180113212321p:plain:w460
進化の方向はそれぞれ

提案モデルの限界

本モデルはもともと、既存のWebアプリケーションの刷新時にどのプログラミング言語を選択すればいいか、という問題意識から生まれたものです。 しかしながら、実際には、あるプラットフォーム上では特定の言語で記述されたアプリケーションしか動作せず、そもそも言語選択の余地がないという場合があります。
また、選択の余地がある場合にも、前述した2つの観点だけでなく

  • (特にBFFであれば)言語レベルでの非同期処理のサポート
  • 言語処理系の多様さ、競争原理が働いているか(例: Java, JavaScript
  • 言語を取り巻くコミュニティの活発さ、持続可能性
  • 開発者の採用難易度や育成難易度

などの観点を考慮して総合的に判断することがほとんどだと思います。

このように、提案モデルは言語選択における観点の全てを網羅するものではありません。 しかしながら、プログラミング言語が持つ特性や素質を整理し、言語の進化の方向を俯瞰するという点においては、わりと筋の良いモデルではないかと考えています。

まとめ

本エントリでは、既存のWebアプリケーションの刷新時にどのプログラミング言語を選択すればいいか、という問題意識から生まれたプログラミング言語の分類モデルを紹介しました。提案モデルは、「型システム」と「並行計算モデルのサポート」という2つの観点からプログラミング言語を分類しようとするものでした。そして、このモデルを実際にいくつかの言語に適用してみることで、2つの観点がそれなりに妥当であることを確認しました。最後に、言語選択の際に考慮すべき他の観点をいくつか挙げ、本モデルがプログラミング言語選択における観点の全てを網羅しているわけではないことを示しました。

このエントリが私と同じような問題を抱えている方の役に立てれば幸いです。

*1:Scalaでは、バージョン2.12で言語に組み込まれていたscala.actorsが削除され、代わりにAkkaの使用が推奨されるようになりました。そのため、厳密には並行計算モデルを言語レベルでサポートしているわけではありません。