elispを再びちょっとだけ勉強
lispには、「シンボル型」があるということを理解する必要があるみたいだ。
>> (setq val 1) 1 >> (setq x 'val) val >> (setq y 'val) val >> (+ x y) ; + の引数にシンボル型が来ているのでエラー ; error >> (+ (eval x) (eval y)) ; eval してやると数値型に評価されるので + の引数になれる 2
これままで、関数の引数は全部評価されてから(evalされてから)関数に渡されると勘違いしていたが、そういう訳ではないことが分かった。
正しくは、関数の引数が
- リスト以外のデータ(シンボル型含む。つまり、アトム)ならそのまま関数の実引数になり、
- リストなら、(func arg ...)という関数適用だと解釈して評価した結果が、関数の実引数になる
というのが正しい理解っぽい。
>> (append (1 1)) ; 1(1)という関数適用だと解釈して評価しようとするのでエラー ; error >> (append '(1 1)) ; 従って、リストを引数にしたければquoteしないとダメ (1 1) >> (setq a 1) 1 >> (+ a 1) ; a の指している先は数値型だから + の引数になれる 2 >> (+ (quote a) 1) ; (quote a) では シンボル型の値が返されるから + の引数になれなくてエラー ; error ; (quote a) という関数適用は評価されるけど、その結果返ってくる a という値を持ったシンボル型のデータは ; 評価されないまま + の引数になる。
多分、やっとこれでlispの基本的なところが理解出来たと思われる。昔は、全然分からんかったので、ちょっと嬉しい。
次は、
>> ((lambda (x) (+ 1 x)) 1) ; これはokなのに 2 >> (setq f (lambda (x) (+ 1 x))) (f 1) ; これな何でダメなのんか ; error
を勉強しよう。