QCon北京での講演の1つ(完売していた)として、Gavin King氏は氏がRed Hatでこの数年の間取り組んでいるプログラミング言語Ceylonについて発表した。このニュースはtwitterで取り上げられ、すでにいくつものサイト、例えばLambda the Ultimate、Slashdot、Reddit、YCombinator Hacker Newsなどでレポートされている。それを受けて、Gavin氏は話題となっているプレゼンテーションへの参照と合わせてCeylonに関する投稿を行った。また、氏はこの言語を決してJavaキラーとしてデザインしたわけではないことを明らかにしている。
それにもかかわらず、私はいくつかのコメントをすべきでしょう。まず第一に、私はこれをJavaキラーや次世代のJava言語として宣伝したのではありません。私の言葉ではありません。CeylonはJavaではなく、Javaに深く影響された新しい言語であり、Javaのファンであると公言してはばからない人々によって設計された新しい言語なのです。Javaが近い将来死んでしまうわけはないし、何もJavaを殺そうともしていません。
JVMベースの言語として、CeylonはバイトコードにコンパイルされてJVMの上でJavaクラスによって実行される。Javaが持っているより制限された形のジェネリクス(ワイルドカードのないジェネリクス)を持ち、メソッドパラメータと戻り値型の共変/反変をサポートする。これによりCeylonは、明示的なキャストオペレータを持つことなくメソッドの戻り値に対する暗黙のキャストを実行することができる。さらに、メソッドはオーバーロードすることができないため、複数の型のメソッドを持つ必要がない。パラメータのキーワードin
とout
は共変/反変のサポートを示す。Ceylonが他のVMにクロスコンパイルされることを妨げるものはないが、まずフォーカスしているのはJVMである。
また、Ceylonは、(Javaでは)オーバーロードされたメソッドのために主に使われるような、メソッドの名前付き引数とデフォルト引数を導入している。メソッドはまたメソッドをとることができ、高階メソッド(すなわち高階関数)をつくる。void
はキーワードとして表されているが、すべては型付けされている(数値リテラルはオブジェクトリテラルと区別されていない)。
Javaユーザにとっては、多くのキーワードが変更されている。例えば、インターフェースに対するimplements
の代わりに、satisfies
を使う。他のキーワードも同様に置き換えられている。public
はshared
になり、protected
とprivate
は使われていない。abstract
はformal
になりactual
が特定のインターフェースの実装を提供する目的で使わる。インターフェースは,
ではなく&
で区切られたリストで組み合わせることができる。
演算子もいくつか提供されている。<=>
演算子はComparableのcompare()
メソッドの省略で、==
はequals()
と同義だ。いくつかの演算子オーバーロードが可能であり、例えば、>
はComparable.largerThan()
と解釈されるが、特定の型でオーバーロードすることができる。演算子の集合そのものは拡張できない(Scalaではメソッドが非ASCII名を持つことを許容しているが、それとはことなる) – が、定義されているものは実装によってオーバーライド可能である。
Ceylonにはnull
がない。代わりに、Optional
型がオブジェクトのインスタンスを提供すると同時に、オプションであることを示す型として使われる。?
接尾辞はOptional値に対する省略形であり、たとえばString?
はOptional<String>
を省略した形である。
また、CeylonはScalaと同じようにミックスイン継承を提供し、あるインターフェースにおいてメソッドを実装することができる。ただし、初期化はできない。(Java 8に対するProject Coinのいくつかがデフォルトメソッドを持つことで同様の振る舞いを提供するかもしれない。)
多くの批評家が質問していることがある:Scalaを使えばいいじゃないか? Gavin氏はこれに対しては特別に次のように回答している:
Scalaは興味深い言語であり、Ceylonに影響を与えたいくつかの言語の1つです。私たちは念入りにScalaを調べましたが、結果的に私たちにとって正しい選択ではないと結論づけました。個人的には、Scalaの型システムは私が欲し、必要としているよりずっと複雑だと理解しています。
Ceylonはキャストをサポートしないので、新しいキーワードcase (is...)
がswitch
文に対して付け加えられていて、特定の型への型安全なキャストを提供している。caseブロックが真なら、caseブロックの内部ではもとのオブジェクトの狭められた型を見ることになる。もしそれがその型でないなら、コードブロックは実行されない。
また、基調講演のプレゼンテーションではモジュラリティ(Scalaにもない機能)について示唆しているが、モジュラリティをどう扱うかについては情報が全く提供されていない。そして、MavenとOSGiの両方を“複雑すぎる”として、同期(synchronization)とともに避けている。(これらに関するGavin氏の回答については下を見よ)
プレゼンテーションに特有の問題を指摘した批評家もいた。たとえば、“JavaはXMLと非常に密接な関係にある”というのは事実上誤りであり、“Javaでユーザーインターフェースを定義するよい方法はまったくない”はライブラリの利用の容易さと混同されているように見える、といったことだ。いくつかのCeylonの例によれば、ユーザーインターフェースはJavaFXのような宣言型で構築されるようだ。GUIユーザーインターフェースは他の技術で構築されることも多いのだが。他にも、インライン関数を定義するための文法が、“Smalltalkから盗んだ”と引用されているのに、Smalltalkのブロックの文法と全く似ていないと酷評するものもいる。ともに間違いではない指摘ではあるけれど、これらは言語そのものというよりはプレゼンテーションに対する批判である。
Ceylonプロジェクトにとって、未来はまだ未定であり、プレゼンテーションはプロジェクトの成果が利用可能になるよりもずっと前に出されたものだ。その結論の中で次のように述べている:
私のチームは過去2年間、あるべきと考える形の言語を設計し、言語仕様を書き、ANTLR文法を書き、プロトタイプコンパイラを書いて過ごしてきた。
- 今はまだこの言語を使ってコードを書くことはできない!
- 私たちは今年の後半にコンパイラの初期リリースを計画している
InfoQでは、Gavin氏に連絡をとり、さらに詳しく聞いた。
InfoQ:CeylonとScalaを比較するたくさんのコメントが出ています。その2つの言語を違ったものにしている主要な点は、Scalaが非ASCIIベース関数を許容することを除いて、どこにあると考えていますか?
Gavin King氏: ええ、Scalaは興味深い言語ですし、Ceylonの設計に影響を与えた言語のうちの1つです。しかし、力点の置き方にいくつかの大きな違いが確実にあります。
CeylonコードはCeylonプログラマでない人にも読みやすくなるようになっています。私たちは読みやすくすることを妨げる文法上の構造を避けています。たとえば、単語の方がわかりやすいような場所での不可解な句読点の利用は避けていますし、真の演算子オーバーロードをサポートすることもしようとしてません。私たちが望んでいるのは、平易で読みやすいコードであり、実行可能なアスキーアートではありません。
Javaは多くを除外することでここまで成功してきました。しかし、ここで賢明になる必要があります。Javaが高階関数のサポートを除外したという決断は、あまりに有害なことでした。いま、明らかにScalaチームはまったく異なった道を進んで、非常に機能の豊富な型システムを作り出しました。一般的なルールとして、私は問題を多くのあまり強力でない構成物で解決するよりも、より少なくより一般的な構成物で解決することを好みます。
私は静的に型付けされたメタモデルを可能にする興味深いものを発明しました。私が言っているのは、リフレクションの型安全なバージョンです。私はこれを提供している他の言語を知りません。私の知らない研究用の言語でこれまでにこの機能が提供されている可能性はありますが。
私たちはまったく新しいSDKを計画しているので、Ceylonは型システムにおいてJavaとの相互運用性に対する多くの譲歩をしません。いくつかのケースでは、その結果としてJavaとの相互運用性に問題が生じることになります。(あまり多くないことを期待していますが!)オーバーロードはありません。存在型もありません。そして、言語仕様のいたるところに隠れたJavaスタイルの"null"もありません。これらはすべて相互運用性シナリオにおいて有用です。が、それらは他のすべてにおいて複雑さという点でとても有害です。おっと、それから、ジェネリック型引数は具象化されることになります。これによって、いくつかの非常に素晴らしい可能性が開けますが、相互運用性を少し害します。
最後に、プロジェクトの主要なゴールの1つは、首尾一貫して、洗練されていて、見た目にも魅力のあるアノテーションのための文法、ユーザーインターフェースと構造化されたデータを定義する文法を提供することです。あなたは"宣言型"プログラミングが好きなら、そのサポートをすることでこれを実現すると考えるかもしれません。今やOracleはJavaFXから離れてしまったので、CeylonはUI開発者にとっての唯一の言語になろうとしているのです!
InfoQ: あなたはMavenやOSGiが有害だと書いています。Ceylonはモジュール化のために何をサポートするのでしょうか?
Gavin King氏: 私たちには、うまく定義されたソースとコンパイラからIDE、そしてランタイムまでの全てにわたるツールチェーンにモジュラリティを統合するためのモジュールリポジトリ仕様を持っているという利点があります。より統制された環境にでは、ずっとシンプルなツールしか必要としません。私たちはJBoss AS 7のコアも形成しているJBoss Modulesと呼ばれるプロジェクトをモジュールランタイムの基礎にしています。JBoss Moduleは非常にシンプルで、小さなモジュールシステムであり、世の中にある他のソリューションよりずっとシンプルです。
InfoQ: 同様に、すべてのオブジェクトはセマフォである(つまり'synchronized'キーワード) と述べています - Ceylonはどのようにマルチスレッドやロックプリミティブをサポートする予定でしょうか?
Gavin King氏: 私は、少なくとも何らかの大きな変化が起こるまでは、並列処理はライブラリが解決すべきことであると強く信じています。言語は並列処理プリミティブを内部にもつ必要はありません。並列処理を扱うための優れているけれど競合するパターンがたくさんあります - アクターからSTMまですべてです。言語はこれらのパターンを実装するライブラリを書くことができるようにすべきです。
InfoQ: あなたはJavaはXMLと非常に密接な関係があると述べています - しかし、それは言語に関しては正しくありません。むしろ、SpringのようなフレームワークがXMLを頻繁に利用しています。これがあなたの言いたかったことでしょうか?
Gavin King氏: 私が言っているのは、言語そのもののなかにエレガントにユーザーインターフェースやほかの静的な階層構造を定義する方法がないということです。したがって、フレームワークは2つの道の1つをとります。手続き的なコードをつかって階層構造を定義する(Swing、Wicket)かXMLに頼るか(JSFや他の多く)です。
InfoQ: なぜ、'void'は型のメンバではなくキーワードなのですか?
Gavin King氏: 実際には"Void"と呼ばれる型があり、それは"void"メソッドの戻り値の型なのですが、小文字の"void"はキーワードです。その理由はメソッド定義内に"return"文は不要であると支持するためです。Ceylonは多くの言語が言語仕様の一部としている概念(例えば、数値型、null値、関数型)を型システム自体の中で表現しています。それが型システム自体がJavaのものよりも非常に強力である必要がある理由です。
InfoQ: 列挙されたサブタイプに対して、サブタイプの集合は閉集合ですか? 言い換えると、クラスNode of Branch | Leaf
があたえられたとき、Node
の第3のサブクラスをつくることはできますか?
Gavin King氏: いいえ。"of"句の目的はコンパイラにこれらが単にサブクラスであると伝えることであり、その結果コンパイラはある型のサブタイプを列挙した"case"文を検証します。これが型安全性を失うことなくビジターパターンを実装するとても便利な方法であると考えることができるでしょう。
InfoQ: 反変/共変型に対して、'in'キーワードや'out'キーワード(これらは他のプログラミング言語ではパラメータが値で返されることを意味する)を使うことは賢明なことなのでしょうか? 他の言語で'in'パラメータや'out'パラメータに慣れている開発者はこれによって混乱しませんか(共変/反変型を理解することとは別として、どちらが有用でしょうか)?
Gavin King氏: そういえば、最近C#チームが独立にまったく同じ文法を作り出していたことを知って、私はかなりこのことについて心強く感じることができました。私はこれが"+"や"-"よりはずっとずっとよいと確信します。別の選択肢は"produces"と"consumes"ですが、それはいくつかの型パラメータがあるような場合あまりに上長になると思います。スマートに保つことはよりよいことだと思いますよ。
InfoQ: あなたは'satisfies'を使っていますが、Javaのような記名式のサブタイプをまだ使っています。新しいキーワードをここに導入することのメリットは何でしょうか?
Gavin King氏: Javaはこの点では変則的です。クラス定義において、1つまたはそれ以上のインターフェースのリストがキーワード"implements"に続きます。インターフェースでは、1つまたはそれ以上のインターフェースのリストがキーワード"extends"のあとに続きますが、偶然にクラス定義内で現れることがあり、そこでは全く違う意味になります(そこでは、単一のクラスが続きます)。Ceylonは規則的です。型のリストは常に"satisfies"の後に続きます。キーワード"extends"は常にスーパークラスをインスタンス化する表現が続きます。
私たちは文法上の規則性は非常に重要だと考えています。
InfoQ: 最後に、これを公の場(例えばQCon以外の場)に公開する計画はどのようなものでしょうか? GitHubから利用できるようにするつもりですか?
Gavin King氏: はい。M1コンパイラリリースの準備ができたら、GitHub上にすべて置くつもりです。しかし、私は文法や型チェッカーをそれと合わせて動くバックエンドを持つことなくリリースしようとはまったく考えていません。正直なところ、私はこんなに早くSlashdotにヒットするとは思っていませんでした ;-)
プレゼンテーションは以下で閲覧可能である: プロジェクトCeylonの紹介(introducing project Ceylon)とCeylon型システム(the Ceylon type system)。 あなたはCeylonについてどう考えますか?