Macros Lisp宏的基本思想

Macros Lisp宏的基本思想,macros,lisp,common-lisp,Macros,Lisp,Common Lisp,我试着用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

我试着用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)
似乎生成的代码(或函数)与原始格式表单不同。我下一步该怎么做

您的“函数一”的问题是您将
&rest
参数按原样传递给
格式
函数。将
x
传递到
formatdf
将导致创建一个包含一个参数的列表,该参数绑定到
allparm
。 因此,如果只想打印第一个参数,则应编写:

 (formatdf t "x is ~a" (car x))
或者用下一种方法修复
格式
内部
格式df

(apply #'format stream string allparm)
“函数一”的问题是,您将
&rest
参数按原样传递给
格式
函数。将
x
传递到
formatdf
将导致创建一个包含一个参数的列表,该参数绑定到
allparm
。 因此,如果只想打印第一个参数,则应编写:

 (formatdf t "x is ~a" (car x))
或者用下一种方法修复
格式
内部
格式df

(apply #'format stream string allparm)
“函数一”的问题是,您将
&rest
参数按原样传递给
格式
函数。将
x
传递到
formatdf
将导致创建一个包含一个参数的列表,该参数绑定到
allparm
。 因此,如果只想打印第一个参数,则应编写:

 (formatdf t "x is ~a" (car x))
或者用下一种方法修复
格式
内部
格式df

(apply #'format stream string allparm)
“函数一”的问题是,您将
&rest
参数按原样传递给
格式
函数。将
x
传递到
formatdf
将导致创建一个包含一个参数的列表,该参数绑定到
allparm
。 因此,如果只想打印第一个参数,则应编写:

 (formatdf t "x is ~a" (car x))
或者用下一种方法修复
格式
内部
格式df

(apply #'format stream string allparm)
宏应该返回源代码,而不是执行。在这里,只有查看宏展开时
allparm
的值才有用。它是源代码的一部分:
(x)

您需要返回一个包含必要说明的列表-这里是调用格式的代码

这是一本关于Lisp的好书,它还应该解释宏的基础知识:

宏应该返回源代码,而不是执行。在这里,只有查看宏展开时
allparm
的值才有用。它是源代码的一部分:
(x)

您需要返回一个包含必要说明的列表-这里是调用格式的代码

这是一本关于Lisp的好书,它还应该解释宏的基础知识:

宏应该返回源代码,而不是执行。在这里,只有查看宏展开时
allparm
的值才有用。它是源代码的一部分:
(x)

您需要返回一个包含必要说明的列表-这里是调用格式的代码

这是一本关于Lisp的好书,它还应该解释宏的基础知识:

宏应该返回源代码,而不是执行。在这里,只有查看宏展开时
allparm
的值才有用。它是源代码的一部分:
(x)

您需要返回一个包含必要说明的列表-这里是调用格式的代码

这是一本关于Lisp的好书,它还应该解释宏的基础知识:

(defparameter nodebug t) (setf x 1) (格式t“x是~a”x);;;生成->x为1

;;;要生成相同版本并准备nodebug版本,需要以下内容:

;;;使用defmacro

(defmacro formatdmadv(流字符串和rest allparm) `(格式、流、字符串、@allparm))

(formattmdadv t“formattmdadv x是~a“x);;;生成->x为1 x为1(定义参数nodebug t) (setf x 1) (格式t“x是~a”x);;;生成->x为1

;;;要生成相同版本并准备nodebug版本,需要以下内容:

;;;使用defmacro

(defmacro formatdmadv(流字符串和rest allparm) `(格式、流、字符串、@allparm))

(formattmdadv t“formattmdadv x是~a“x);;;生成->x为1 x为1(定义参数nodebug t) (setf x 1) (格式t“x是~a”x);;;生成->x为1

;;;要生成相同版本并准备nodebug版本,需要以下内容:

;;;使用defmacro

(defmacro formatdmadv(流字符串和rest allparm) `(格式、流、字符串、@allparm))

(formattmdadv t“formattmdadv x是~a“x);;;生成->x为1 x为1(定义参数nodebug t) (setf x 1) (格式t“x是~a”x);;;生成->x为1

;;;要生成相同版本并准备nodebug版本,需要以下内容:

;;;使用defmacro

(defmacro formatdmadv(流字符串和rest allparm) `(格式、流、字符串、@allparm))


(formattmdadv t“formattmdadv x是~a“x);;;生成->x是1 x是1您可以对其进行优化,这样您就不必约束列表:
(应用#'格式流字符串allparm)
apply
期望最后一个参数实际上是一个参数列表,但由于我们提供了一个
&rest
参数,因此实现可以自由优化,例如,将参数留在堆栈中而不考虑列表。您可以优化它,这样就不必约束列表:
(应用#格式流字符串allparm)
apply
期望最后一个参数实际上是一个参数列表,但由于我们提供了一个
&rest
参数,实现可以自由优化,例如,以这样的方式将参数留在堆栈中而不考虑列表。您可以优化它,这样就不必约束列表:
(应用#格式流字符串allparm)