kagamihogeの日記

kagamihogeの日記です。

JEP 126: Lambda Expressions & Virtual Extension Methods をテキトーに訳した

http://openjdk.java.net/jeps/126 のテキトーな訳。

JEPをもいっこくらい読んでみるかぁ~ってことで、概要レベルくらいは抑えているラムダ式んとことを読むことにした。

JEP 126: ラムダ式と仮想拡張メソッド Lambda Expressions & Virtual Extension Methods

Author    Joseph D. Darcy
Organization    Oracle
Owner   Brian Goetz
Created 2011/11/1
Updated 2013/2/21
Type    Feature
State   Funded
Component   --/--
Scope   SE
JSR 269 MR, 335
Discussion  lambda dash dev at openjdk dot java dot net
Start   2011/Q4
Blocks  107, 109
Effort  XL
Duration    XL
Reviewed-by Brian Goetz
Endorsed-by Brian Goetz
Funded-by   Oracle
Release 8
Target  M7

要約 Summary

ラムダ式(クロージャclosures)とそのサポート機能、これに付随するものとして、メソッド参照(method references)、拡張型インタフェース(enhanced type inference)、仮想拡張メソッド、をJavaプログラミング言語とプラットフォームへ追加する。

目的 Goals

ラムダ式と仮想拡張メソッドの主要機能、それに沿ったサポート機能のセット、いくつかのプラットフォーム目標。

  • より抽象化されたハイパフォーマンスライブラリの消費と作成の簡素化。
  • 移行互換性のあるスムーズなライブラリ進化のサポート

新しく共通な機能をJavaプログラミング言語に追加することに加えて、ラムダ式は内部イテレーションイディオム(internal iteration idioms)により改良マルチコアサポートに新しい可能性を与えます。

ラムダ周りに採用される言語機能には仮想拡張メソッドが含まれており、これはインタフェースにソースとバイナリ互換における改良をもたらします。

言語変更に加えて、coordinated libraries*1JVM変更が同様に発生します。

注意点として、JEPプロセスで以前の日付で活動中および継続中のProject Lambda OpenJDKプロジェクトと、それに対応するJSR、JSR 335、はJava 8がターゲットになります(JSR 336)。

Non-Goals

関数型(function types)の言語機能とgeneral control abstraction*2Javaへのラムダ式追加の目的ではありません。しかし、将来的にそうした機能追加をしないという意味ではありません。

動機 Motivation

多くの良く使われているオブジェクト指向プログラミング言語で、JVM上で動作するもの(例えば、Grooovy, Ruby, Scala)と仮想マシン上で動作するもの(CLR上のC#)は、クロージャをサポートしています。それゆえに、Javaプログラマーは次第にクロージャをサポートするプログラミングモデルと言語機能に精通するようになりました。

特に興味深いこととしては、クロージャ内部イテレーションのイディオムを可能にします。現在の配列とコレクションは外部イテレーション(external iteration)をサポートしており、これはイテレーションの制御ロジックがトラバースされるデータ構造の外側に存在*3しています。たとえば、配列かコレクションをforでループ処理するのは外部イテレーションの一例です。Javaforループセマンティクスは、厳格な順次イテレーション(strict serial iteration)を命じます。この意味は、プログラマが標準コレクションをイテレーションする方法について、すべての利用可能なコアの使用が許可されていない、ということになります。

内部イテレーションでは、データ構造に実行用のコード片がラムダ式として渡され、データ構造が計算のパーティショニングと結果出力の責任を負います。データ構造は自身の内部的な詳細を知っているので、以下のようなオプションによって計算にとってより良いスケジューリングが選択できる可能性が発生します。

  • 実行順序の入れ替え(Alternate execution order)
  • スレッドプールを使用したコンカレント実行
  • パーティショニングとwork stealing*4を使用したパラレル実行。Java SE 7で追加されるfork/join frameworkは、パラレル実行フレームワークの候補の一つであり、コア数の広範囲で動作するperformance-robustなパーティショニングを提供します。

内部イテレーションスタイルのプロトタイプ例としては、下記のようなfilter-map-reduce操作のシーケンスとなります。

int maxFooWeight =
    collection.filter( /* isFoo述語を指定する */)
              .map(    /* ラムダ式でFooのweightをmapする */)
              .max();  /* reduceする */

ラムダ式とは、要求される操作を表現するための簡潔なシンタックスによる、式です。このスタイルは、コレクションの順序付イテレーションを不必要に拘束しがちな、一つ以上の明示的なforループの代わりとなるものです。加えて、良く練られたアルゴリズムは、パラレルな操作セットの実行だけでなく、三つの操作を単一のパラレルパスに集約可能です。

Project Lambdaはまた、仮想拡張メソッドも含んでいます。これは、ソース互換性の懸念のために、広く使われているインタフェースにメソッドを追加することが出来ない長年の制限に対処するものです。

拡張メソッドを、java.util.Collectionjava.util.Listのような、既存のコレクションインタフェースに加えることにより、それらの型の既存実装で新しいプログラミングイディオムを使用可能になります。JDK(等)のそれらの型の実装は、高パフォーマンスもしくは他の特殊実装を提供するために、スーパーインターフェースの拡張メソッドのデフォルト実装をオーバーライド可能です。

説明 Description

進行中のOpenJDKのProject Lambdaページ対応するJSRが、この取り組みの詳細に関する最新の情報を掲載しています。

全体的なProject Lambdaの取り組みによって影響を受けるプラットフォームのコンポーネントは以下のようなものになります。

代替案 Alternatives

straw-man提案で開始されたProject Lambdaと、"ラムダの軌跡"イテレーションを辿ることにより、プロジェクトのシンタックスと機能セット両方が発展してきました。

Project Lambdaのラムダ式部分に関する研究はこれまでに数々の努力が知られており、下記がすべてではないですがその一部です。

Project Lambdaの機能セットは、それ以前の提案よりも、Javaプラットフォームを改善するニーズに取り組むという、ベターな選択をしました。

仮想拡張メソッドの設計も同様に、プログラミング言語コミュニティにおいて従来から多くの研究が知られています。例えば、

他の言語環境と比較すると、Java言語は常に予測可能なセマンティクスを持ってきました。それは、既知のサイズである組み込みプリミティブタイプ、厳密な位置でスローされる例外、厳密に定義されている式の実行順序、など。自動パラレル化(auto-parallelization)を許可するために、組み込みforwhileループのセマンティクスを緩めることは、望ましく無く、マルチコアサポートの目的を達成するのに十分でもない、と判断されました。

テスト Testing

ユニット/リグレッションテストに加えて、新言語機能のJCKテストも開発されるでしょう。

機能のユーティリティーも、JDKプラットフォームライブラリでの使用を通して検証されます。

リスクと仮定 Risks and Assumptions

巨大な取組がプラットフォームの多くの側面に影響を及ぼすので、予期せぬ複雑な事態や相互作用が発生する可能性があります。

複数回のイテレーション計画および計画の早期開始をすることで、たとえば、サポートライブラリの開発などにより、複雑な事態のインパクトは軽減されるべきです。

依存性 Dependences

ラムダ式の現在推奨される実装方法は、invokedynamicJSR 292で導入されたメソッドハンドル(method handles)に、依存しています。それゆえ、ラムダの許容パフォーマンスは、メソッドハンドルとその他の要因の許容パフォーマンスに依存します。

JEP 107109のライブラリ動作と言語機能間でのフィードバックが予想されます。

インパクト Impact

  • 他のJDKコンポーネント:他のJDKコンポーネントインパクトは説明(Description)の項目で要点を説明しました。
  • 互換性:仮想拡張メソッドはinterfaces.add仮想拡張メソッドによるソース互換性改良を許可することを目的としています。
  • セキュリティ:セキュリティ・レビューがラムダのランタイム実装の領域において必要とされます。
  • パフォーマンス/スケーラビリティ:ラムダフレンドリーなイディオム VS 伝統的なイディオム、は記録されるべきでしょう。
  • ドキュメント:ユーザーガイドとサポートドキュメントを作成する必要があります。
  • TCK:大きなプラットフォーム機能なので、言語とライブラリTCKを開発する必要があります。

*1:何のことだ……

*2:何のことだ……

*3:livesなのでちっとニュアンスが違うが……

*4:日本語でなんていうか知らんけど、こういうスケジューリングの話では見かける単語なので、まぁ分かる人には分かるんでしょう