Vim 8.0 で追加された Vim script の機能 Lambda

Vim 8.0 ではついに Vim script に Lambda が追加されました! Lambda を定義する場合は { args -> expr } という構文を使用します。

" Lambda は関数参照を返す
" epxr にはその名の通り "式" のみ書くことができる
let F = { a, b -> a + b }

echo F(1, 2)
" => 3

また filter() 関数などに直接 Lambda を渡すことも出来ます。

echo filter(range(1, 10), { index, val -> val % 2 == 0 })
" => [2, 4, 6, 8, 10]

[変数のキャプチャ]

次のように Lambda 外のローカル変数もキャプチャされます。

function! s:main()
    let value = 10
    let F = { a -> value + a }
    echo F(5)
   " => 15
endfunction
call s:main()

[Lambda 内では式しか定義できない]

Lambda 内では式のみ定義できるので、コマンドなどを直接呼び出すことは出来ません。

" このような使い方は出来ない
let Nonumber = { -> set nonumber }

この場合は、同じく Vim 8.0 で追加された execute() 関数を使用します。 execute() は引数のコマンドを実行する関数になります。

" execute() を経由してコマンドを呼び出す
let Nonumber = { -> execute("set nonumber") }

このように execute() を経由することでコマンドを式として呼び出すことが出来ます。

[引数に a: をつける必要はない]

Lambda 内で使用する引数には a: をつける必要はありません。 ですので次のように外部の引数を参照することも出来ます。

function! s:main(arg)
    let F = { a -> a:arg + a }
    echo F(5)
   " => 15
endfunction
call s:main(10)