2016/01/09

特殊形式は高階手続きと一緒に使うことができない

手続きは引数を全て評価してoperatorに渡す.
特殊形式は引数を全て評価するとは限らない.
ここではdefineについて見てみる.
defineは第1引数は評価せず,第2引数を評価した値を第1引数に束縛する.

(define x (+ 1 2))
(+ 1 2)
3
(define x 3)
x
3

次のような高階手続きでdefineを使ってみる.

(define (test f a b) (f a b))
(test define x 1)
*** ERROR: unbound variable: x
Stack Trace:
_______________________________________
  0  x

  1  (eval expr env)
        At line 179 of "/usr/local/Cellar/gauche/0.9.4/share/gauche-0.9/0.9.4/lib/gauche/interactive.scm"

まずtestの引数を全て評価する.
xを評価した時点でunboundなのでエラーが返る.
仮にxには2が束縛されていると,どうなるか.

(define x 2)
x
(test define x 1)
*** ERROR: invalid application: (#<syntax define> 2 1)
Stack Trace:
_______________________________________
  0  (eval expr env)
        At line 179 of "/usr/local/Cellar/gauche/0.9.4/share/gauche-0.9/0.9.4/lib/gauche/interactive.scm"

数字リテラルの2に数字リテラルの1を束縛しようとしてエラーが返る.
変数xのまま扱うには評価しないようにしなくてはならないが,
高階手続きはあくまで手続きなので引数を全て評価してしまう.
他の特殊形式(ifやset!など)も同様に使えない.


© 2022 wat-aro