Macros “实习生”职能的目的是什么?
下面是作者定义以下宏的地方:Macros “实习生”职能的目的是什么?,macros,common-lisp,symbols,Macros,Common Lisp,Symbols,下面是作者定义以下宏的地方: (defmacro make-is-integral-multiple-of (n) (let ((function-name (intern (concatenate 'string (symbol-name :is-integral-multiple-of- ) (wr
(defmacro make-is-integral-multiple-of (n)
(let ((function-name (intern (concatenate
'string
(symbol-name :is-integral-multiple-of- )
(write-to-string n)))))
`(defun ,function-name (x)
(equal 0 (mod x, n)))))
宏很容易阅读和理解,但我想知道:我们何时以及为什么明确需要intern
函数
删除它会中断宏,然后宏返回错误:
The value "IS-INTEGRAL-MULTIPLE-OF-3"
is not of type
(OR SYMBOL CONS).
这是否意味着每次宏定义新符号时都必须调用intern
?在defmacro
语句之外是否有intern
的用法?欢迎提供见解。查找或创建
具有包中提供的名称的符号
这意味着在宏创建符号时必须使用它。
您的示例中的宏是一个相当典型的用例,除了人们通常使用诸如:is integral multiple of-
之类的非预期符号,而不是关键字:is integral multiple of-
在其他情况下,它可能是有用的。
一般来说,包是将字符串映射到符号的专用表,intern
对应于(setf gethash)
例如,您可以使用以下方法之一保存数据:
(defvar *operators* (make-hash-table :test 'equal))
(defstruct operator name help function)
(defun make-op (name help function)
(setf (gethash name *operators*)
(make-operator :name name
:help help
:function function)))
(make-op "build-house"
"construct a house out of the supplied materials"
(lambda (bricks mortar) ...))
(funcall (operator-function (gethash "build-house" *operators*))
(list "brick1" "brick2" ...)
(make-mortar))
或
使用
符号名称
访问操作员名称,帮助是符号值
函数名称
函数名的类型必须为(或符号CONS)
。这是通用Lisp标准所要求的
因此,名称需要是符号或列表。Lisp中的函数名通常必须是符号。它们可以是列表对于setf函数来说是比较特殊的。在Common Lisp中,它只能是类似于(setf foo)
的列表,第一个符号是setf
。普通公共Lisp中不允许使用其他列表作为函数名。(旁注,旧的Lisp机器Lisp有其他列表作为函数名)
以下是不寻常的,实际上是Common Lisp的一个功能:
(defun (setf a) (new-value thing) ; (setf a) is the name of the function
(setf (first thing) new-value))
使用INTERN和MAKE-SYMBOL生成函数名
因此,如果您想生成一个新的函数名,它需要是一个符号。首先将新名称生成为字符串,然后从该字符串生成符号
有几种方法可以创建符号INTERN
将查看该符号是否已存在于包中(当前包为默认值)。如果它不存在,它将创建一个新的符号并在该包中插入该符号
也可以使用MAKE-SYMBOL
创建符号,但该符号不会出现在任何包中。这使得通常很难访问该符号
通常,函数名应该是一个符号,它位于某个包中。只有在极少数情况下,例如在某些计算代码的情况下,将不需要的符号作为函数名才有用
(defun foo (bar) ; FOO is a symbol and the name of the function
(+ 42 bar))
(defun (setf a) (new-value thing) ; (setf a) is the name of the function
(setf (first thing) new-value))