我尝试在Lisp中做一个非常简单的事情 - 找到一种方法来打开一个全局有价值的nodebug t然后一些调试格式形式将是沉默。为此,我发现我无法理解以下内容的区别:
(defparameter *nodebug* t)
(setf x 1)
;;; the basic function
(format t "x is ~a" x) ;;; generate -> x is 1
;;; try to use function not macro
(defun formatdf (stream string &rest allparm) ;;; later add (if ...
(format stream string allparm))
(formatdf t "x is ~a" x) ;;; generate -> x is (1)
;;; try to use macro
(defmacro formatdm (stream string &rest allparm) ;;; later add (if ...
(format stream string allparm))
(formatdm t "x is ~a" x) ;;; generate -> x is (X)
生成的代码(或函数1)似乎与原始格式形式不同。我的下一步应该是什么?
答案 0 :(得分:2)
(defmacro formatdm (stream string &rest allparm) ;;; later add (if ...
(format stream string allparm))
宏应返回源代码,而不是执行。这里只看到allparm
在宏扩展时的值是有用的。它是源代码的一部分:(x)
。
您需要返回一个包含必要说明的列表 - 这里是调用格式的代码。
这是一本关于Lisp的非常好的书,它也应该解释宏的基础知识:http://www.cs.cmu.edu/~dst/LispBook/
答案 1 :(得分:1)
“功能一”的问题在于您将&rest
参数原样传递给format
功能。将x
传递给formatdf
会导致创建一个包含一个参数的列表,该列表绑定到allparm
。
因此,如果您只想打印第一个参数,您应该写:
(formatdf t "x is ~a" (car x))
或以下一种方式在format
内修复formatdf
:
(apply #'format stream string allparm)
答案 2 :(得分:0)
(defparameter nodebug t) (setf x 1) (格式t" x是~a" x);;;生成 - > x是1
;;;要生成相同的并准备nodebug版本,需要以下内容:
;;;使用defmacro
(defmacro formatdmadv(stream string& rest allparm) `(格式,流,字符串,@ allparm))
(formatdmadv t" formatdmadv x is~a" x);;;生成 - > x是1< - 宏正确
;;;或建议使用defun
(formatdf_car t" formatdf_car x is~a" x);;;生成 - > x是1< - fun correct
(defun formatdf(stream string& rest allparm) (应用#'格式(list * stream string allparm)))
(formatdf t" formatdf using apply x is~a" x);;;生成 - > x是1< - fun correct
;;; ----以下是不正确的
(defun formatdf_err(stream string& rest allparm)(格式化流字符串allparm))
(formatdf_err t" formatdf_err:x is~a" x);;;生成 - > x是(1)
(defun formatdf_car(stream string& rest allparm) (格式化流字符串(car allparm)))
(defmacro formatdm(stream string& rest allparm) (格式化流字符串allparm))
(formatdm t" formatdm x是~a" x);;;生成 - > x是(X)
;;; -----测试确认结果
(pprint(macroexpand-1'(formatdm t" formatdm x is~a" x)))
(pex(macroexpand'(formatdm t" formatdm x is~a" x)))
(pprint(macroexpand-1'(formatdm t" formatdm b" c)))
;;; ---错误的一个,甚至不生成源代码
(pprint(macroexpand-1'(formatdmadv t" formatdmadv x is~a" x)))
(pprint(macroexpand'(formatdmadv t" formatdmadv x is~a" x)))
(pprint(macroexpand-1'(formatdmadv t" formatdmadv b" c)))