Sim*_*mon 2 lisp evaluation clisp common-lisp
如何知道函数是否评估其参数?
Setq似乎没有评估它的论点
Break 15 [16]> (setq j (kjl klj))
*** - EVAL: undefined function KJL
Run Code Online (Sandbox Code Playgroud)
那么评估何时完成?
cond并且and似乎也没有评估他们的论点,但......
Break 18 [19]> (cond ((eql nil nil) (write "lkj")))
"lkj"
"lkj"
Break 18 [19]> (cond ((eql nil (not nil)) (write "lkj"))
NIL
Run Code Online (Sandbox Code Playgroud)
在上面的例子中,cond必须评估(eql nil nil)以确定它是否真实,不是吗?
例如,当你编写时(eql a 1),函数eql获取变量a的值和文本1本身的值.
运行时也未评估的参数的宏(如cond和and).宏将其参数转换为代码,然后由运行时进行评估.
例如,当你写作时cond ((eql nil nil) (write "lkj"))),它会扩展为:
> (macroexpand '(cond ((eql nil nil) (write "lkj"))))
(IF (EQL NIL NIL)
(PROGN (WRITE "lkj"))
NIL)
Run Code Online (Sandbox Code Playgroud)
然后if根据其规范评估表单作为特殊运算符.
当然,您不想实际阅读宏扩展cond以了解它的作用 - 您阅读了doc.但是,您确实用于macroexpand调试自己的宏.
运行时处理特殊运算符(例如setq),特别是,即每个特殊运算符的行为都是特殊的.
例如,当你编写时(setq a (! 4)),运行时没有进行评估a,但它确实评估(! 4),它发现它!是一个函数的fbound,所以它计算4(它计算自身),然后调用!with参数的函数绑定4,并指定将value(24)返回给变量a.
实际上,正如@Paulo在评论中提到的那样,首先检查符号是否为特殊运算符(因为实现可以将宏实现为特殊运算符和vv); 它不能同时是一个宏和一个函数(但你可以使用编译器宏).这超出了这个问题的范围,但......
在Emacs中编辑你的代码,加载clhs.el,并查看你感兴趣的符号的文档.这将立即说明符号的定义.