如何更改aif以便能够在宏单元中访问'it'而不在包中公开'it'

Sim*_*Sim 3 common-lisp

如果你把介绍的AIF代码onlisp在一个包,并尝试在其他您在PACKAGENAME问题上运行使用它:它不是外部.

(in-package :packagename)

(defmacro aif (test-form then-form &optional else-form)
  ‘(let ((it ,test-form))
     (if it ,then-form ,else-form)))
Run Code Online (Sandbox Code Playgroud)

想要调用语法

(in-package :otherpackage)

(aif (do-stuff)
  (FORMAT t "~a~%" it)
  (FORMAT t "just got nil~%"))
Run Code Online (Sandbox Code Playgroud)

我怎样才能在代码中修复这种行为,而不是将变量外包在包声明中,并且it只能通过it而不是packagename:it

Lex*_*Lex 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))))
Run Code Online (Sandbox Code Playgroud)

或者这也有效:

(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))))
Run Code Online (Sandbox Code Playgroud)