Up: Home
Clojureをつくったわけ
Rich Hickey
(翻訳 丸井淳史)
2009年11月28日(土)
The original document appears at http://clojure.org/rationale. The translation is based on November 27, 2009 version of the page.
読みにくくて申し訳ないです。数多くの間違いがあると思いますので、ご指摘ください。
顧客や出資家は、業界標準のプラットフォームであるJava仮想マシン (Java Virtual Machine; JVM) に相当な投資をしており、そのパフォーマンス、セキュリティ、安定性などに満足している。Java開発者は、動的言語の簡潔さ、柔軟さ、生産性をうらやましく思うものの、顧客の環境で動かせるかどうか、既存のコードやライブラリが使えるかどうか、そして動作速度などについて心配するかもしれない。また、ネイティブ・スレッドやロッキングによる並行処理に頭を悩ましているかもしれない。こうした文脈において、Clojureは実用的な動的言語--現在Javaが用いられている分野で同様に使うことができる汎用動的言語--を開発する試みでもある。また、並行処理プログラミングの未来のためにも、いま蔓延している``適正に管理されていない変種''はすぐに舞台から退場すべきである。
Clojureはその目的に次のように対応している。業界標準かつオープンなプラットフォームであるJava仮想マシンを利用し、由緒正しいLispを現代化し、イミュータブルで永続的なデータ構造により関数型プログラミングを発展させ、そしてソフトウェア・トランザクショナル・メモリと非同期型エージェントを用いて、並行処理をネイティブ・サポートする。できあがったのは堅牢で実用的かつ高速な言語だ。
なぜ私は新しいプログラミング言語を書いたのだろうか。次のような特徴を持つ言語が見つからなかったから、という理由からだ。
- 並行処理のために設計された、
- 定評のあるプラットフォームと相性がよい、
- 関数型プログラミングのための、
- Lisp。
以下ではClojureの特徴や開発理由などを簡単にまとめた。
- アイディアを真似されたり盗まれたりしているが、まだ完全なコピーはされていない
- ラムダ計算のおかげで非常に小さい言語である
- 文法がないに等しい
- 同図像性 (Homoiconicity; コードとデータが等しいこと) と構文抽象化による優位性
- 標準化されたLisp (Common LispとScheme) は?
- 標準化以降の発展がない (もしくは発展が遅い)
- 標準データ型はミュータブル (変数の値が変更可能) で、拡張もできない
- 仕様に並行処理がない
- Java仮想マシン用の良い処理系がすでに存在する (ABCL、Kawa、SISCなど)
- 標準化されたLispは、独自のプラットフォームになっている
- Clojureは後方互換性にとらわれないLispである
- 同図像性の考え方をmapやvectorにも拡張している
- デフォルトでイミュータブル (変数の値が変更不可)
- 標準データ型も拡張可能
- 既存のプラットフォーム(JVM)を採用している
- イミュータブルなデータ + 関数リテラル
- Lispでも規制や慣習で可能
- でもデータ構造が変化可能だったら、変化しないと仮定するのは危険
- 伝統的なLispではリストのデータ構造のみが構造的に再帰的
- 純粋に関数型の言語は静的型付けがほとんど
- みんなが使えるわけじゃない、どんなことにでも使えるわけじゃない
- Clojureは動的型付けをする関数型言語
- すべてのデータ構造がイミュータブルで永続的、再帰をサポート
- ヘテロジニアス(異種混合)なコレクション、戻り型
- 動的な多態性(ポリモーフィズム)
- OSではなく仮想マシンこそが未来のプラットフォームだ。仮想マシンによって以下のものが提供される。
- 型システム
- ライブラリ
- OSの抽象化
- 莫大な機能
- 内蔵およびサード・パーティによるもの
- メモリなどのリソース管理
- ガーベッジ・コレクションは言語でなくプラットフォームの機能であるべき
- バイトコード & JITコンパイル
- ``プラットフォームとしての言語'' 対 ``言語+プラットフォーム''
- 昔ながらのやり方--それぞれの言語が独自のランタイムを定義
- ガーベッジ・コレクション、バイトコード、型システム、ライブラリなど
- 新しいやり方 (JVM、.Net)
- ``プラットフォームのために作られた言語'' 対 ``プラットフォームに移植された言語''
- 新しい言語は「プラットフォームとしての言語」のアプローチをとることが多い
- 別のプラットフォームに移植するときには、プラットフォーム上にプラットフォームを作るという問題が出てくる
- メモリ管理、型システム、スレッドなどの問題
- ライブラリの重複
- オリジナルがC言語ベースだとしたら、Cで書かれた拡張ライブラリは付いてこない
- クライアントに要求されたプラットフォーム
- 「JVM or .Netで動作すべき」対「Unix or Windowsで動作すべき」
- JVMは十分な経験と信頼を得ている
- 他のコードとの相互運用が必要
- Java/JVMは``言語+プラットフォーム''
- 新しい話ではないが、他にもJVM用の言語は存在していた。いまではSunのものになっているものも。
- Javaはめんどくさかったり、必要以上に冗長になるきらいがある
- Javaの機能が利用できることは必須
- Clojureは言語、JVMはプラットフォーム
- シミュレーション分野で生まれ、今では何にでも(不適切な分野でさえ)使われている
- Java/C#ではどんな状況においてもオブジェクト指向を使うことになっており、それ以外の方法をとることができない
- ミュータブルで状態のあるオブジェクトは新時代のスパゲッティ・コードだ
- 理解し、テストし、論理立てて考えることは難しい
- 並行処理においては壊滅的
- 多態性(ポリモーフィズム)を実現する方法は継承だけではない
- 「10のデータ型に使う10の関数があるより、1つのデータ型に使う100の関数があるほうがましだ」--アラン・J・パリス
- Clojureはデータ構造をインターフェースによるイミュータブル・オブジェクトとして実現している。それ以外に独自のクラスシステムは提供しない。
- 多くの関数が数少ないデータ型のために定義されている (seq、map、vector、setなど)
- JavaでJavaを書く。ClojureではJavaを利用し拡張する。
- switch文、構造的なパターン・マッチングなどは、不安定なシステムの原因になる
- 多態性によって、拡張性と柔軟性のあるシステムが開発できる
- Clojureのマルチメソッドは多態性をオブジェクト指向や型から切り離している
- 複数のタクソノミーをサポートする
- 静的、動的、外部のプロパティやメタデータによるディスパッチ
- イミュータブルなオブジェクトは並行処理の問題をなくしてくれる
- しかし、オブジェクトの状態を変化させることは、シミュレーションであったり、プログラムから外の世界への窓口としての利用のみ現実的 (訳注:ここ自信ない。原文は「But changing state a reality for simulations and for in-program proxies to the outside world」)
- ロックを正しく書くことは難しすぎる
- ClojureのSTM (Software Transactional Memory; ソフトウェア・トランザクショナル・メモリ)は、その難しい部分を引き受けてくれる
短く言えば、Clojureは強力な並行処理をサポートしたJava仮想マシンのための実用的なLispであると言える。featuresでその機能を確かめてもらいたい。
Up: Home
MARUI Atsushi
2013-01-12