kagamihogeの日記

kagamihogeの日記です。

JEP 323: Local-Variable Syntax for Lambda Parametersをテキトーに訳した

http://openjdk.java.net/jeps/323 を読んだ。

JEP 323: Local-Variable Syntax for Lambda Parameters

Author   Brian Goetz
Owner   Vicente Arturo Romero Zaldivar
Created 2017/12/08 15:15
Updated 2018/02/12 17:25
Type    Feature
Status  Targeted
Component   specification/language
Scope   SE
Discussion  amber dash dev at openjdk dot java dot net
Effort  XS
Duration    XS
Priority    3
Reviewed by Alex Buckley
Release 11
Issue   8193259
Relates to  JEP 286: Local-Variable Type Inference

Summary

暗黙的に型指定されるラムダ式(implicitly typed lambda expressions)の仮引数宣言でvarを使用可能にします。

Goals

ローカル変数宣言と暗黙的に型指定されるラムダ式の仮引数宣言でのシンタックスを揃える。

Non-goals

メソッドの仮引数などその他の変数宣言は対象外。

Motivation

ラムダ式は暗黙的な型指定が可能で、この場合はすべての仮引数は型推論されます。

(x, y) -> x.process(y)    // 暗黙的に型指定されるラムダ式

Java SE 10ではローカル変数で暗黙的な型指定が使用可能になります。

var x = new Foo();
for (var x : xs) { ... }
try (var x = ...) { ... } catch ...

ローカル変数の統一感の観点から、暗黙的に型指定されるラムダ式の仮引数でも'var'を使えるようにしたい、と我々は考えました。

(var x, var y) -> x.process(y)   // 暗黙的に型指定されるラムダ式

統一感によるメリットには、修飾子やnotably annotationsをローカル変数とラムダ式の仮引数に、簡潔さを失うことなく、適用できる点です。

@Nonnull var x = new Foo();
(@Nonnull var x, @Nullable var y) -> x.process(y)

Description

暗黙的に型指定されるラムダ式の仮引数で、予約済みの型名varを使用可能にします。

(var x, var y) -> x.process(y)

上記は以下と同等です。

(x, y) -> x.process(y)

暗黙的に型指定されるラムダ式は、すべての仮引数でvarを使うか、全く使わないか、のどちらかでなければなりません。また、varは暗黙的に型指定されるラムダ式の仮引数でだけ使用可能で、明示的に型指定されるラムダ式では引き続きすべての仮引数でマニフェスト型(manifest types)を指定します。よって、マニフェスト型の仮引数を使いつつvarも使うことは出来ません。以下の使い方は出来ません。

(var x, y) -> x.process(y)         // 暗黙的に型指定されるラムダ式で'var'と'非var'を一緒には使えない
(var x, int y) -> x.process(y)     // 暗黙的に型指定されるラムダ式で'var'とマニフェスト型を一緒には使えない

理屈の上では、上記例の下側、半明示的な型指定(semi-explicitly typed )(もしくは半暗黙的な型指定(semi-implicitly typed)、どちらに重きを置くかの見方の違いに依る)のようなラムダ式は可能に見えます。しかし、このJEPではそれはスコープ外とし、これは型推論オーバーロード解決に深く影響するためです。これが、ラムダ式ですべてマニフェスト引数型にするか全くしないか、という制限を設ける主な理由です。同様に、暗黙的に型指定されるラムダ式の引数での型推論varを使うか全く使わないか、という制限を設ける考えです。将来のJEPでこの部分推論(partial inference)の課題に取り組むかもしれません。また、省略のシンタックスの簡潔さを損ないたくないので、以下のような表現が出来るようにはしない予定です。*1

var x -> x.foo()

Alternatives

従来通りJava SE 8 の暗黙的に型指定されるラムダ式の宣言を使用し続ける。

Risks and Assumptions

このJEPの、暗黙的に型指定されるラムダ式の引数名の前にvarを追加するのは、ソース互換性に関してはノーリスクです。これはvarなし引数の型推論var型推論は同一なためです。

*1:Also, we do not wish to compromise the brevity of the shorthand syntax, so we won't allow expressions like:が原文。compromise がよくわからん