Common lisp 如何在宏的帮助下定义一堆东西?
我必须Common lisp 如何在宏的帮助下定义一堆东西?,common-lisp,sbcl,Common Lisp,Sbcl,我必须defconst64个值在我的程序中,并且鉴于Lisp拥有我至今从未使用过的著名宏工具,我认为这是我的机会。但它似乎不像我预期的那样起作用 (defun square-name (square-index) (multiple-value-bind (row col) (floor square-index 8) (format nil "SQ-~A~D" (string (code-char (+ (char-code #\A)
defconst
64个值在我的程序中,并且鉴于Lisp拥有我至今从未使用过的著名宏工具,我认为这是我的机会。但它似乎不像我预期的那样起作用
(defun square-name (square-index)
(multiple-value-bind (row col) (floor square-index 8)
(format nil "SQ-~A~D"
(string (code-char (+ (char-code #\A) col)))
(+ 1 row))))
(defmacro defconst-all-square-names ()
(dotimes (i 64)
`(defconstant ,(make-symbol (square-name i)) ,i)))
(defconst-all-square-names)
鉴于我对lisp和macros比较陌生,有人能解释一下吗
- 如何实现定义这些常量的目标,而不必自己键入它们
- 如果我不能使用宏,为什么
- 宏必须返回要执行的代码
- 我使用
的构造没有达到预期效果,我不得不使用(make symbol…
)(intern…
(defun square-name (square-index)
(multiple-value-bind (row col) (floor square-index 8)
(format nil "SQ-~A~D" (string (code-char (+ (char-code #\A) col))) (+ 1 row))))
(defmacro defconst-all-square-names ()
(append '(progn)
(loop for i from 0 to 63 collect
`(defconstant ,(intern (square-name i)) ,i))))
(defconst-all-square-names)
让我们看一下时间:
* (dotimes (i 10) 42)
NIL
上面的dotimes
表单返回NIL
,与()
->空列表相同。基本上它什么也不返回
因此,宏不返回任何内容。因此,代码(defconst all square names)
扩展为()
。用macroexpand-1
检查是否正确
总而言之:
- 你的宏没有副作用
- 由于宏返回
()
记住:宏的第一个用途是生成代码。->您需要生成代码,否则需要键入。由于宏确实返回
()
,运行()
自然不会产生任何效果->现在什么都不会发生。让我们看看dotimes
:
* (dotimes (i 10) 42)
NIL
上面的dotimes
表单返回NIL
,与()
->空列表相同。基本上它什么也不返回
因此,宏不返回任何内容。因此,代码(defconst all square names)
扩展为()
。用macroexpand-1
检查是否正确
总而言之:
- 你的宏没有副作用
- 由于宏返回
()
记住:宏的第一个用途是生成代码。->您需要生成代码,否则需要键入。由于宏返回
()
,运行()
自然没有效果->什么也不会发生。只有在我写(defmacro defconst all square names()(从0到63循环收集
(defconstant,(make symbol(square name I)),它也不工作…@BitTickler(foo)(foo)(foo))
在Common Lisp中不是有效代码。如果您打算生成一系列表单,那么您需要生成例如(progn(foo)(foo)(foo))
(defmacro defconst all square names()(append(progn)(从0到63的循环collect`(defconstant,(make symbol(square name i)))不是吗…@bittickler:你怎么知道的?您是否使用了macroexpand-1
查看生成的代码?如果您查看生成的代码,您可以很容易地看到另一个错误…让我们来看看。只有当我编写(defmacro defconst all square names()(从0到63的循环collect
(defconstant,(make symbol(square name I)),I))`它也不工作…@BitTickler((foo)(foo)(foo))
在Common Lisp中是无效的代码。如果您打算生成一系列表单,那么您需要生成例如(progn(foo)(foo)(foo))
(defmacro defconst all square names()(append(progn)(从0到63的循环collect`(defconstant,(make symbol(square name i)))不是吗…@bittickler:你怎么知道的?您是否使用了macroexpand-1
查看生成的代码?如果您查看生成的代码,您可以很容易地看到另一个错误…让我们来看看。