如何在宏的帮助下 defconst 一堆东西?
How to defconst a bunch of stuff with the help of a macro?
我必须在我的程序中 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 和宏比较陌生,有人可以解释一下吗,
- 我如何在不自己输入常量的情况下实现定义这些常量的目标。
- 如果我不能使用宏,那是为什么?
也许我只是错过了一些宣言或类似的东西。上面的代码在没有警告或错误的情况下编译,并且在加载它之后(为此使用 emacs、slime 和 CTRL-C-K),定义了 none 个常量。
更新
在与@Rainer Joswig 聊了聊之后(非常感谢!)结果是,
那
- 宏必须return要执行的代码
- 我用
(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
:
* (dotimes (i 10) 42)
NIL
return上面的dotimes
形式NIL
,同()
->空列表。基本上return没什么。
所以你的宏 return 什么都没有。因此代码 (defconst-all-square-names)
扩展为 ()
。使用 macroexpand-1
.
检查
总结一下:
- 你的宏没有side-effect
- 您的宏扩展为一个空列表,因为您的宏 returns
()
您需要修复后者。
记住:宏的第一个目的是生成代码。 -> 你需要生成代码,否则你需要输入。由于您的宏 return ()
和 运行 ()
自然不会产生任何影响 -> 什么都没有发生。
我必须在我的程序中 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 和宏比较陌生,有人可以解释一下吗,
- 我如何在不自己输入常量的情况下实现定义这些常量的目标。
- 如果我不能使用宏,那是为什么?
也许我只是错过了一些宣言或类似的东西。上面的代码在没有警告或错误的情况下编译,并且在加载它之后(为此使用 emacs、slime 和 CTRL-C-K),定义了 none 个常量。
更新
在与@Rainer Joswig 聊了聊之后(非常感谢!)结果是, 那
- 宏必须return要执行的代码
- 我用
(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
:
* (dotimes (i 10) 42)
NIL
return上面的dotimes
形式NIL
,同()
->空列表。基本上return没什么。
所以你的宏 return 什么都没有。因此代码 (defconst-all-square-names)
扩展为 ()
。使用 macroexpand-1
.
总结一下:
- 你的宏没有side-effect
- 您的宏扩展为一个空列表,因为您的宏 returns
()
您需要修复后者。
记住:宏的第一个目的是生成代码。 -> 你需要生成代码,否则你需要输入。由于您的宏 return ()
和 运行 ()
自然不会产生任何影响 -> 什么都没有发生。