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

を勉強しよう。