我对宏和函数之间的区别感到困惑; 特别是为什么第二部分失败,因为第一部分成功.
(defun foo () "foo")
(setf a 3) ;; sets the symbol value cell to 3
(setf a #'foo) ;; PART ONE
(funcall a) ;; returns foo
(defmacro bar () "bar")
(setf b #'bar) ;; Error the macro name bar was found as an argument to function PART TWO
Run Code Online (Sandbox Code Playgroud)
宏不是函数.因此,您无法从宏名称获取函数对象.您可以应用函数,但不能应用宏.
宏需要源代码并生成新的源代码.
Common Lisp以这样的方式定义,即可以在运行时之前在编译时完成.Common Lisp在一般情况下不支持运行时宏扩展.Common Lisp这样做可以在运行之前完全编译代码.定义Common Lisp的目标之一是将其定义为允许高效执行大型Lisp程序的语言.运行时代码生成仅在受控方式下有用 - 否则可能在运行时发生全新的执行错误类.允许一般运行时代码操作的宏机制不被认为是可取的.
在较旧的Lisp方言中,存在所谓的FEXPR的概念,它类似于宏,可以在运行时调用,并且可以将源作为运行时进行操作.Common Lisp已删除此功能.有关此背景,请参阅Kent Pitman的Lisp特殊表格.