Shammer's Philosophy

My private adversaria

特定関数呼出中のみの予約語を定義する

自分のやろうとしていることの日本語がこれでよいのか、、、ちょっと心配なところもあるが、JSP で使用できる request とか out というようなものを自分で定義したい。一番基本的なところから考えてみるか。まず、以下のような関数を定義する。

? (defun a () (format t "~A~%" xxx))
;Compiler warnings :
;   In A: Undeclared free variable XXX
A
?

xxx は quote してないし、トップレベルで変数として定義されていなければ上記のような結果は想定通り。いや、Warning にはなるが定義できる、というだけですごいかもしれない。Java だとコンパイルすらできないんじゃないだろうか。が、これは実行すれば当然エラーになる。

? (a)
> Error: Unbound variable: XXX
> While executing: A, in process listener(1).
> Type :POP to abort, :R for a list of available restarts.
> Type :? for other options.
1 >

だが、この関数を test1.lisp として保存し、別の main.lisp を以下のよう作成し、

(defparameter xxx "0123456789")
(load "test1.lisp")
(a)
(quit)

実行すればエラーなく処理は完了する。

$ ccl64 -l main.lisp
0123456789
$

main.lisp を少し変更し、let にしても問題はない、と思ったが、、、

(let ((xxx "0123456789"))
  (load "test1.lisp")
  (a))
(quit)

実行結果は以下。

$ ccl64 -l main.lisp
;Compiler warnings for "/private/tmp/main.lisp" :
;   In an anonymous lambda form at position 0: Unused lexical variable XXX
;Compiler warnings for "test1.lisp" :
;   In A: Undeclared free variable XXX
> Error: Unbound variable: XXX
> While executing: A, in process listener(1).
> Type :GO to continue, :POP to abort, :R for a list of available restarts.
> If continued: Skip loading "main.lisp"
> Type :? for other options.
1 >

どうやら、トップレベルで定義されていないとダメなのかもしれない。これは、、、ちょっと困った。