Common lisp 如何将aif更改为能够访问';它';在宏调用中,不进行';它';包装中的公共物品

Common lisp 如何将aif更改为能够访问';它';在宏调用中,不进行';它';包装中的公共物品,common-lisp,Common Lisp,如果您将中提供的aif代码放在一个包中,并尝试在另一个包中使用它,那么您运行的问题是packagename:它不是外部的 (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

如果您将中提供的aif代码放在一个包中,并尝试在另一个包中使用它,那么您运行的问题是packagename:它不是外部的

(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
而不是
packagename:it
访问
it

(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))))

它可以工作,但不是有一种更优雅的方式,让后来的宏读者知道这些“奇怪”行的意图是什么?哪些行是“wierd”行?在我看来,
(让((从字符串“it”)读取)
行不自我解释
intern
也在当前包中实习符号(默认),并明确表示这是你的意图。这就是它的目的。