3

onlispで提示された aif コードをパッケージに入れ、それを別のパッケージで使用しようとすると、packagename:it が外部ではないという問題が発生します。

(in-package :packagename)

(defmacro aif (test-form then-form &optional else-form)
  ‘(let ((it ,test-form))
     (if it ,then-form ,else-form)))

必要な呼び出し構文

(in-package :otherpackage)

(aif (do-stuff)
  (FORMAT t "~a~%" it)
  (FORMAT t "just got nil~%"))

パッケージ宣言で変数を外部にせずに、コードでこの動作を修正するにはどうすればよいですitか?itpackagename:it

4

1 に答える 1

5
(defmacro aif (test then &optional else)
  ;;; read-from-string will intern the symbol
  ;;; in the current package, with the correct
  ;;; read-table-case
  (let ((it (read-from-string "it")))
    `(let ((,it ,test))
       (if ,it ,then ,else))))

またはこれも機能します:

(defmacro aif (test then &optional else)
  ;;; (intern "IT") or (intern "it") will work
  ;;; as well, depending on your readtable settings.
  ;;; using string or symbol-name gets around that.
  (let ((it (intern (string 'it))))
    `(let ((,it ,test))
       (if ,it ,then ,else))))
于 2012-09-12T16:07:21.777 に答える