まとめ
このPRにより、
Vim scriptの準標準ライブラリであるvital.vimのData.Listモジュールで、
Funcref(ラムダ式や関数参照)が使用可能になりました!
Vim scriptでFunctional Programmingを楽しもう!
lets:L= vital#vital#new().import('Data.List')let xs = range(0,50)let xs =s:L.map(xs,{x-> \(x % 5==0)&& (x % 3==0) ? 'FizzBuzz' \:(x % 5==0) ? 'Fizz' \:(x % 3==0) ? 'Buzz' \: string(x)\})function!s:p(x) abort
returna:x==# 'Fizz'endfunctionlet xs =s:L.filter(xs,function('s:p'))
echo s:L.all(function('s:p'), xs)" 1
背景
Vim8.0でラムダ式がサポートされましたので、
Data.ListがFuncrefに対応する必要がありました。
このPR以前では下記のような、
式を表す文字列を渡すことしかできませんでした。
これはVim scriptの伝統的な方法です。
lets:L= vital#vital#new().import('Data.List')
echo s:L.map(range(0,9),'v:val + 1')" [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
今回の追加で
下記のように、
Funcref(ラムダ式、関数参照)を使用することができるようになりました!
lets:L= vital#vital#new().import('Data.List')function!s:succ(x) abort
returna:x+1endfunction" ラムダ式let Succ ={x->x+1}" 関数参照let Succ_ =function('s:succ')let xs = range(0,9)
echo s:L.map(xs, Succ)==s:L.map(xs, Succ_)" 1
Vim scriptの古き伝統ともおさらば
おまけ
Data.List.Closure
vital.vimには、
Vim8.0より前のVimでも関数の部分適用を行うためのData.Closureモジュールが存在します。
今回のPRでは、
Data.ClosureのオブジェクトでData.Listの各関数を使用するためのData.List.Closureモジュールも追加されました。
lets:V= vital#vital#new()lets:C=s:V.import('Data.Closure')lets:CL=s:V.import('Data.List.Closure')function!s:plus(x,y) abort
returna:x+a:yendfunctionlet plus =s:C.from_funcref(function('s:plus'),[10])let xs = range(0,9)
echo s:CL.map(xs, plus)" [10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
Data.List.Closureはパフォーマンスに難があるため、
Data.List内の直接対応は見送られました。
ですので基本的には、
Vim8.0で追加されたclosure付き関数(ラムダ式)
またはfunction関数による部分適用
との組み合わせでData.Listを使用した方がよいでしょう。
以上
Vim scriptでFunctional Programmingを楽しもう!
Data.OptionalとData.Eitherもあるよ!
@ Milly
実は本PRは途中で「Vim 7.4のみでVim scriptのパースエラーが起きる」という問題に出くわしていて、
遥かなるだるみによって放置してしまっていました。
そこでその対応をしてくださったのがMillyさんでした。
ありがとうございました!