Java言語の生産性とパフォーマンスの追求を続けている、OracleのJava言語アーキテクトであるBrian Goetz氏は、Java SE 12 Java Language Specificationで定義されている現在のキーワードセットでは新機能の追加が困難なであるという理由から、同社でJava言語とJava Virtual Machineの仕様リーダを務めるAlex Buckley氏と共同で、すでに定着したキーワードを進化させるためのハイフン付きキーワードセットの提案を行った。
JDK-8223002の記載内容によれば、ハイフン付きキーワードを実装する目的は次のようなものだ。
- Java言語デザイナが新機能を提示できるように、構文的選択をオープンにする手段の探求
- キーワードトークンが極めて少なく貴重であるがために、言語デザイナが現状のキーワードに合わせるように、Javaプログラミングモデルを制約ないし改変しなければならない、という問題の解決
- さまざまな種類の機能に適したキーワードのスタイルを、言語デザイナにアドバイスするため
言語を進化させる手段としては、いくつかのテクニックが長年にわたって使用されてきた。[a] 土地収容(eminent domain) — 識別子をキーワードとして再分類する方法(Java 1.4のassert
、Java 1.5のenum
など)。[b] オーバーロード — 既存のキーワードを新機能で再利用する方法。[c] 歪(distortion) — 既存のキーワードを使って構文を作る方法(@interface
など)。[d]煙と鏡(smoke and mirror) — 新しいコンテキストで使用される新しいキーワードのイリュージョンを作り出す方法(ローカル変数限定のvar
など)。これらの手法はいずれも、何らかの形で問題を抱えている。例えば、キーワードとしてassert
を追加したことにより、ほぼすべてのテストフレームワークが使用不能になった。
ハイフン付きキーワードの概念は、これら従来の技術を補完して、既存の古典的(classic)キーワードおよび/または文脈的(contextual)キーワードを組み合わせて使用するものだ。古典的キーワードとは、"識別子としてではなく、常にキーワードとしてトークン化される一連のJava文字"であり、文脈的キーワードとは、"特定のコンテキストではキーワードとして、他のすべてのコンテキストでは識別子としてトークン化されるJava文字のシーケンス"である。提案されたハイフン付き古典的キーワードはnon-final
、break-with
、value-class
などで、ハイフン付き文脈的キーワードはnon-null
、read-only
、eventually-true
などだ。
ハイフン付きキーワードを実装する場合の問題のひとつは、任意先読みあるいは固定先読みの字句解析器(Lexer)が、a-b
などの式を3つのトークン(識別子、演算子、識別子)に解析するか、あるいはハイフン付きキーワードとして解析するか、という点に関わりがある。
今年初めのOpenJDKメーリングリストでの会話によると、JDK 13(2019年9月リリース予定)では、ハイフン付きキーワードのbreak-with
導入が提案されていた。しかしながら、最終的にbreak-with
キーワードは削除され、新たなキーワードyield
を加えたswitch
式が再レビューされることになった。新たなswitch
式の構造が最終的に完成すれば、2年近く議論されてきたパターンマッチングの概念を導入する方法も明確になるはずだ。
Goetz氏とBuckley氏は、ハイフン付きキーワードというコンセプトの長所と短所について、次のようにコメントしている。
シンプルさを理由として機能を除外することには問題ありませんが、明確なセマンティクスを示す方法がないから、という理由は受け入れられません。これは言語の進化において常に発生する問題であり、すべてのJava開発者が継続的に支払うべき税金なのです。
新たなキーワードを作らずに生きる方法のひとつは、Javaの進化を完全に止めることです。これが素晴らしいアイデアだと思う人がいたとしても、利用可能なトークンがないためにそうするのだ、というのは馬鹿げた理由でしょう。Javaは今後も長く使える言語であり、Java開発者たちは、表現力が豊かで信頼性の高いコードを作成できる新機能を待ち望んでいるのです。
提案されたこれらのハイフン付きキーワードについて、Goetz氏が説明してくれた。
InfoQ: Java言語のハイフン付きキーワードに対して、コミュニティの反応はどうでしたか?
Goetz: ご想像のとおり、賛否はさまざまでした。成熟した言語を進化させる最適な方法は何か、という問題に注意を払っている人もいれば、私たちが"針の先で天使が何人踊れるか"の哲学的考察をしている(どうでもよいことに拘っている)と不満を述べて、もっと自分たちの希望する機能に取り組んでほしい、と言う人たちもいました。
InfoQ: もしハイフン付きキーワードの提案が受け入れられなければ、Java言語のキーワードセットを拡張するために、"土地収用"、"オーバーロード"、"歪み"、"煙と鏡"といった既存テクニックが再び使用されることになるのでしょうか?
Goetz: それも選択肢だと思います。興味深い、柔軟な新オプションがメニューに追加された、ということでしょう。ただし、どのような状況においても、他にもっと優れた選択肢がある可能性はあります。どんな方法も排除するつもりはありません。
InfoQ: JEP 354によると、ハイフン付きキーワードとして提案されたbreak-with
は、JDK 13の新たなキーワードであるyield
によって削除されましたが、Java言語で初のハイフン付きキーワードを採用しないという決定に至った理由は何ですか?
Goetz:
break-with
はハイフン付きの一番有力な候補でしたが、ユーザの目にはまだ見慣れない、意味の不明確なもののようでした。ハイフン付きキーワードはメニューにはあっても、すべての食事でそれを注文しなければならない、という意味ではありません。全体的には、yield
の方が自然だと思われたのです(ただし、当然ですが、コルーチンから値を返すことを連想させることから、それを好まない人もいました)。yield
は、特定の文法位置に配置する、文脈的キーワード(すべての文法位置で同じ意味とは限らない)の適切な候補であったと言えます。
InfoQ: 6か月のリリースサイクルによってJavaの進化が速くなったことで、最終的にハイフン付きキーワードがJava言語に導入される可能性はどの程度になったのでしょうか?
Goetz: 必要であればメニューにある、という状態です。例えばSealed型には
non-sealed
のように、制約を解除する方法が必要になるかも知れません。
InfoQ: ハイフン付きキーワードに関して、これだけは読者に知って欲しいという、最も重要なメッセージは何ですか?
Goetz: 言語の互換性の進化と、可読性の維持とのバランスを取ることに、私たちが真剣に取り組んでいる、ということですね。
リソース
- Brian GoetzがJavaのパターンマッチングについてInfoQに語った (2017/9/17)
- Brian Goetz氏によるbreak-with提案 (2019/1/17)
- Alex BuckleyによるJava言語のキーワード管理に関する提案 (2019/4/25)