Humanity

Edit the world by your favorite way

Vimスクリプトでlambda-like Funcref

こんなのできたらうれしい。
Vimスクリプトでlambdaっぽいものができる。


これは
本の虫: シンタックスシュガーとしてのlambdaの解説
にインスパイアされた。
実際lambdaがない言語でこれと似たようなことをすればlambdaは実現できると思う。
ただ動的に辞書に関数を代入できる必要がある。

C++コンパイラがあるので問題ないとして、
VimスクリプトではFuncref*1というものがあるので

let dict = {}
function! dict.func()
    echo 'hello'
endfunction

let dict = {}
function! Hello()
    echo 'hello'
endfunction
let dict.func = function('Hello')

といったことができる。
なのでbindfn()みたいなことはきっとできるはず。


Vimスクリプトでは参照はないので、self.varの元の値を変化させる場合は
参照型である辞書型か配列に保存しておき、その変数にアクセスする場合は
両方でその辞書型か配列の変数を見ればいい。


ただ一般的なプログラミング言語の話として、
lambdaに値を変化させられるとかなり保守性が悪くなる。
id:pi8027さんとこの辺話して気づかされたけど、
変数を束縛できるというclosureの性質はすごく有用だけど、
変数の値まで変わってしまうとかなり保守性が悪くなる。大事なことなので2回言いました。
なので結論として、closureは「変数」そのものを束縛させるのではなくて、「値」を束縛するものと考えるべき。


id:pi8027さんに言わせれば副作用が諸悪の根源ということなのだろうけど
副作用大好きな変態Vim scripter*2僕としてはそういう結論になったのでした。


さぁパパbindfn()作っちゃうぞー。大学の課題終えたらorz

ちなみに

「そもそもVimスクリプトにlambda構文を導入すればいいんじゃない?」と言う人はeval.cを100回ぐらい見るといいよ。

*1::help Funcref

*2:というかそもそもVimスクリプトで副作用を扱わずにプログラミングするのは至難の業