PR

Project Lambda

 前置きが長くなりましたが、Project Lambdaでの提案を紹介していきましょう。

 Project LambdaではBGGAの提案の機能をほとんど受け継いでいるようです。しかし、記述はより簡潔です。

 記述に関してはStephan Colebourne氏、Stephan Schulz氏によるFirst-class methods: Java-style closure (FCM)を受け継いでいるようです。

ラムダ式

 まずは無名関数としてのラムダ式の記述方法です。

 ラムダ式の記述方法は2種類あります。

    #( 引数 )( 式 )

もしくは

    #( 引数 ) { ブロック }

 #がラムダ式の開始を表しています。つまり、#が関数型のためのリテラルになります。

 では、実際にラムダ式を書いてみましょう。まず、常に10を返すラムダ式です。

    #()( 10 )

 引数はないので、はじめのカッコには何も入りません。そして、次のカッコで返す値を記述します。

 Javaでは値を返すというとreturnですが、ここでは式の値がラムダ式の値として帰ります。

もちろん、オブジェクトを返すことも可能です。

    #()( new Date() )

    #()( new ArrayList<Integer>() )

    #()( {1, 2, 3} )

 最後の例はProject Coinで提案されているリストの記述方法です。

 次に引数のある場合です。

    #(int x)( x + x )
 
    #(int x, int y)( x * y )
 
    #(long time)( new Date(time) )

 引数は#の後のカッコに記述します。引数が複数ある場合は、カンマで区切って列挙します。

 ブロックで記述する場合も、同じように記述します。

    #(int x) {
        x + x;
    }
     
    #(int x) {
        return x + x;
    }

 上記の2種類の記述法は全く同じ処理を表しています。ブロックにreturnを記述しない場合、最後に記述した式の値が返ります。

 ブロックの中にループやif文を記述することもできます。

    #(int x) {
        if ( x > 0 ) {
            return true;
        } else {
            return false;
        }
    }

 ラムダ式といっても特に難しいことはありません。ブロックで記述すれば、ほとんどメソッドと同じ感覚で記述することができます。

 また、ラムダ式の中であっても、例外をスローすることも可能です。

関数型

 ラムダ式が記述できるようになったので、ラムダ式を代入する変数を記述してみましょう。そのためには、変数の型を定義する必要があります。

 ラムダ式は関数型として扱います。関数型の定義は次のように記述します。

    # 戻り値の型 (引数の型)(throws 例外)

 これだけだとわかりにくいので、具体的な例を示します。

    #int() ten = #()( 10 );
 
    #int(int) doubler = #(int x)( x + x );
 
    #int(int, int) multiplier = #(int x, int y)( x * y );
 
    #Date(long) dateFactory = #(long time)( new Date(time) );
 
    #boolean(int) signChecker = #(int x) {
        if ( x >= 0 ) {
            return true;
        } else {
            return false;
        }
    };
 
    #void(String) logger = #(String message) {
        System.out.println(message);
    }

 最後の例のように、ラムダ式の返り値がない場合はvoidとして扱います。

 メソッドの引数や戻り値にラムダ式を使用することもできます。

    #double() foo(#double(int) func) {
  
            ...
        
        return #()( Math.rondom() );
    }

 ラムダ式が例外をスローする場合、引数の型の後に括弧を用いて記述します。

    #String(String)(throws IOException) fileReader = #(String filename) {
            ...
            
        throw IOException();
            
            ...
            
        return ...;
    }

 複数の例外がスローされる場合、カンマ区切りで列挙します。