next up previous
Next: 4 関数閉包(closure) Up: ソフトウェア特論 講義資料 クロージャ,オブジェクト指向 Previous: 2 第一級身分

3 Funarg問題(Function Argument Problem)

Lispでは,関数をデータとして扱えるようになっていますが,関数をデータと して扱えるようにする場合には, Function Argument Problem(funarg問題)が おこります. ラムダ式で与えられた関数の実行中に自由変数(そのラムダ式の中ではバイン ドされていない変数)の取り扱いがはっきりとしないために問題となります. たとえば,引数としてラムダ式を渡す場合の例をあげてみます.

(defun down-foo (x)
   (down-baa '(lambda () (+ x 1))))

(defun down-baa (f &aux (x 100))
   (funcall f))

(defun down-baa (f)
  ((lambda (x) (funcall f)) 100))

(defun down-foo (x)
   (down-baa (quote (lambda () (+ x 1)))))

(defun down-foo2 (x)
   (down-baa (function (lambda () (+ x 1)))))

(defun down-foo3 (x)
   (down-baa #'(lambda () (+ x 1))))
この関数で (down-foo 10)とやった場合に何が返るべきかという問題です. down-fooから ラムダ式 (lambda () (1+ x)) で表される関数が down-baa へ の引数として渡さ,down-baaの中でその渡された ラムダ式内の変数 x(=10) が down-fooで渡された x なのか,down-baa の 局所変数である x(=100) べ きなのかという問題です. また,関数がラムダ式を値として返す場合にも同じような問題が生じます.

(defun up-foo (x) '(lambda () (1+ x)))

(defun up-baa (x) (funcall (up-foo 100)))
として,(up-baa 10)と呼んだ場合に,11が返るべきか101が返るべきかという 場合です.引数として渡す場合を downward funarg, 結果として返す場合を upward funargと呼ぶ場合もあります. 関数をデータとして扱えるようにするためには,このfunarg問題を解く必要が あります.このfunarg問題を解決するために,Common Lispでは,関数データ として関数閉包(functionclosure) を明確に定義することでこのような問題が 起こらないようになっています.

generated through LaTeX2HTML. M.Inaba 平成18年5月6日