Next: 4 関数閉包(closure)
Up: ソフトウェア第三 講義資料 クロージャ,スコープ,遅延評価,オブジェクト,立体モデル
Previous: 2 第一級身分
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では,関数データ
として関数閉包(function closure) を明確に定義することでこのような問題が
起こらないようにしている.
generated through LaTeX2HTML. M.Inaba 平成18年5月7日