”なぜScalaなのか?”という質問に答える前に、”Scalaとは何か?”という質問に最初に答える必要がある。ScalaのWEBサイト(source)から、以下の概説を見ることが出来る。
Scalaは、簡潔かつエレガント、そして型安全な手法で、一般的なプログラミングパターンを表現するために設計された、複数のパラダイムを持つ近代的なプログラミング言語です。それは関数型言語とオブジェクト指向の機能を、スムーズに統合しています。
- Scalaはオブジェクト指向です: Scalaは、全ての値がオブジェクトであるという意味においては、純粋なオブジェクト指向言語です。オブジェクトの型と振舞いは、クラスとその特性として記述されます。クラスの抽象性はサブクラス化と、mixinをベースとした柔軟なコンポジションメカニズムによって拡張されます。後者については、複数継承のクリーンな代替方法です。
- Scalaは関数型です: Scalaは、全ての関数が値である、という意味においては関数型言語でもあります。Scalaは、匿名関数を定義するための軽量な文法を提供しており、高階関数をサポートし、関数のネストも可能で、カリー化もサポートされています。Scalaの場合、クラスとそのビルトイン (関数) によって、多くの関数型プログラミング言語で利用されてきた代数型や、パターンマッチングモデルがサポートされています。
- Scalaは静的に型付けされます: Scalaは静的に強制され、安全で明快な規則にのっとった抽象化が利用される、表現力豊かな型システムを備えています。
- Scalaは拡張可能です: 「実際のところ、ドメイン固有のアプリケーションはドメイン固有言語による拡張をしばしば必要とする」と言う事実に基づき、Scalaは設計されています。Scalaは、ライブラリと言う形で新しい言語の構造をスムーズに追加する、ユニークな言語機能の組み合わせを提供しています。
これらの機能が組み合わさることにより、文法の拡張や、マクロ的なメタプログラミング機能を必要とすることなく、新しいステートメントの定義を行えるようになります。
- あらゆるメソッドを2項演算子、もしくは後置演算子として使用することができます。
- そして、期待される型に基づいて (ターゲット・タイピング) クロージャが自動的に生成されます。
- Scalaは、JAVA/.NETと相互運用性を持つ: ScalaはJava 2実行環境(JRE)や.NETフレームワーク(CLR)のような、人気のあるプログラミング環境とうまく相互運用できるよう設計されています。とりわけ JavaやC#といった本流のオブジェクト指向言語とは、可能な限りスムーズに相互作用します。ScalaはJavaやC#と同じようなコンパイルモデル(個別コンパイル、動的なクラスローディング)を持っており、質の高い数千ものライブラリにアクセスすることが可能です。
一部の開発者にとっては、こうしたインセンティブにより、JavaからScalaに乗り換える理由はすでに十分かもしれない。しかしその他の人にとっては、現在Javaによって行っている日々のプログラミングにとって、更なる利益がもたらされるわけではないのだ。
だからこそもう一度言いましょう。"なぜScalaなのか?"
”Scala: RubyとJavaの双方にとってのベスト(source)”というエントリの中で、Ianは「JavaかScalaか、という選択ではなく、JavaとScalaを組み合わせて使うことで、Rubyのような他の言語の代わりになるかもしれません」と述べている。
多くのプログラマがRubyを愛しており、好きで好きでたまりません。それはおそらくJavaが初めて登場して以来、最も激しく福音を説かれてきた言語のひとつです。彼らは大抵、柔軟で拡張性のある文法やクロージャ、そしてコードがどれほど簡潔で表現豊かかを引き合いに出します。
例えば、以下のようにシンプルなシンタックスでマップを作る事ができます。(Rubyでは”ハッシュ”と呼ぶ。ハッシュテーブルはマップを実装する唯一の手段です)
numberMap = {"one" => 1, "two" => 2, "three" => 3}
これをJavaで書くととても面倒です :
Map numberMap = new HashMap(); numberMap.put("one", 1); numberMap.put("two", 2); numberMap.put("three", 3);
では、Scalaだとどうでしょう?Scalaでのマップの例を見てみましょう。
var numberMap = Map("one" -> 1, "two" -> 2, "three" -> 3)
Ruby のコードと非常によく似ているのがお分かりでしょう。しかし、いくつか重要な違いがあります。具体的には、ScalaのコンパイラーはJavaのように、 numberMapがキーにはStringクラスを、値にはIntegerクラスを使うことを知っています。Javaとは違い、そうした指定を行う必要はありません。マップそれ自身が判断するのです!これは”型推論"と呼ばれています。
これが意味するのは、もし私が新たなキーと値をnumberMapに追加しようとする際、キーにIntegerクラス、値にStringクラスを使うとすれば、Scalaがコンパイル時にすぐにエラーを出す (もしくは、あなたの使っているIDEが警告を出す) という事です。Rubyでは、ソフトウェアを実行し、マップからキーと値をとりだそうとする際、期待するStringとIntegerではなくIntegerとStringを取得した時に、初めて問題となります。
実行時に発生するバグをある程度除去できるという点で、コンパイル時の型チェックによって節約できる時間は馬鹿になりません。そしてScalaは冗長なコーディングなしに、こうしたメリットをもたらすのです。
ちゃんとした例で、コードの記述量が減るのをさらに見たいのであれば、Ted Newardが自身のブログ「Scalaパート2: 簡潔さ(source)」において、Java、C#、Visual Basic、Ruby、Scalaで開発されたクラスの違いを研究している。
続けて、Ianはこう述べている。
Scalaはそのほかにも、クロージャを含めてJavaに欠けている、Rubyの良い機能をたくさん持っています。そしてScalaを"ドメイン固有言語"とするのに適した、非常に柔軟なシンタックスを持ちます。こうした機能の全てを持ち、静的な型付けの利便性を損なうことなく、それらを組み合わせることができます。
この意見は、David MacIverのブログにある「いや本当に、なぜScalaなのか?(source)」に共通するものである。彼はその記事で、オブジェクト指向プログラミング、モジュール指向プログラミング、静的型、関数プログラミング、implicitなど、Scalaの中でも彼が好きな特徴を挙げている。彼は以下のように付け加えている。
Scala は完成には程遠いです。Javaから引き継いだ変な文法や多少の問題、そこそこバグのあるコンパイラ、記憶しきれないほどたくさんのちょっとした機能などがあります。しかしながら、実際のところこれらの問題は、時々あなたたちをイライラさせる以上のことはしません。ただ座ってよいコードを書く分には、コアとなる言語はパワフルで、非常に便利です。
バランスのとれた見解を提供するために、Davidは引き続きブログの記事「なぜScalaじゃないか(source)」において、いくつかの特徴的なケースにおいて話を膨らませている。要約すると、Davidの意見は次のようなものである。
全般的に見て、これらについては単にイライラすることも多いと思います。私にとっては未だに好きなJVM向け言語ですが、あなたにとっては、重要と思える事項の優先順位次第です。
Scalaが言語として成熟してきているのを見せるため、「Scalaによるプログラミング(source)」と言う本がもうすぐ発売される。待ちきれない場合はArtimaのWebサイトから、印刷前のバージョンをPDFで手に入れることができる。
彼らのウェブサイト(source)をご覧になり、自身でScalaについてよく確認してみてほしい。