lisp - 如何知道函数是否评估其参数?

标签 lisp common-lisp evaluation clisp

如何知道函数是否对其参数求值?

Setq 似乎不评估它的参数但是

Break 15 [16]> (setq j (kjl klj))
*** - EVAL: undefined function KJL

那么评估什么时候完成?

condand 似乎也没有评估他们的论点,但是......

Break 18 [19]> (cond ((eql nil nil) (write "lkj")))
"lkj"
"lkj"
Break 18 [19]> (cond ((eql nil (not nil)) (write "lkj"))
NIL

在上面的示例中,cond 必须评估 (eql nil nil) 才能知道它是否为真,不是吗?

最佳答案

理论:Form Evaluation

函数

运行时在将参数传递给 function 之前评估参数(例如 eql )。

例如,当您编写 (eql a 1) 时,函数 eql 获取变量 a 的值和文字 1 本身。

运行时评估 macros 的参数(例如 condand )。 宏将它们的参数转换为代码,然后由运行时评估。

例如,当您编写 cond ((eql nil nil) (write "lkj"))) 时,它会扩展为如下内容:

> (macroexpand '(cond ((eql nil nil) (write "lkj"))))
(IF (EQL NIL NIL)
    (PROGN (WRITE "lkj"))
    NIL)

然后是 if形式根据其作为特殊运算符的规范进行评估。

当然,您不想真正阅读 cond 的宏展开式了解它的作用 - 你阅读了文档。但是,您确实使用了 macroexpand调试您自己的宏。

特殊运算符

运行时句柄 special operators (例如 setq ),好吧,特别,也就是说,每个特殊运算符的行为都是特殊的。

例如,当您编写 (setq a (! 4)) 时,运行时不会评估 a,但是,它会评估,计算 (!4),它发现 ! 被绑定(bind)到一个函数,所以它计算 4(它是 evaluates to itself),然后调用! 与参数 4 的函数绑定(bind),并将返回值 (24) 分配给变量 a

订单

实际上,正如@Paulo 在评论中提到的,首先检查符号是否为特殊运算符(因为实现可以将宏实现为特殊运算符和 vv);它不能同时是一个宏和一个函数(但你可以使用 compiler macros )。这超出了这个问题的范围......

练习:使用 CLHS

在 Emacs 中编辑代码,加载 clhs.el , 并查看您感兴趣的符号的文档。 do 会立即说明符号定义为什么。

关于lisp - 如何知道函数是否评估其参数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24998521/

相关文章:

parsing - 具有不同结合性和相同优先级的相邻运算符的表达式消歧

javascript - 如何在javascript中终止父函数的执行?

linux - SBCL 错误 : "binding stack exhausted" when running Maxima on Linux machine

clojure - 在 Liberator Clojure 中发布未返回 200 OK

lisp - 获取列表中 elt 的 cdr

common-lisp - cl-html-parse 中的 ASCII 流解码错误

functional-programming - 方案函数的位置独立参数

functional-programming - LISP 中的 REVERSE 函数

common-lisp - 在 common lisp 中访问向量

r - 使用 data.table 的 'by' 中的符号列表