我正在关注 Paul Graham 的《On Lisp》一书,其中第 5.7 节说“尖引号 lambda 表达式是常量,但对构造函数的调用将在运行时进行评估。 ”
这让我想起了 Lisp 代码数据二元性的一般原则。
有人可以帮忙解释一下函数在计算机内存中表示时如何是常数吗?当然,这只是一组指令,但函数仍然接受输入,所以这是否意味着运行时的实际执行不是恒定的?
最佳答案
这意味着函数是一个不能被修改的常量对象。就像一把铲子:你不能更换铲子,但你可以用它挖许多不同的沟渠。同样,您无法更改该函数,但可以将其应用于不同的参数并获取不同的值。
顺便说一句,对于所有实现来说,情况并不一定总是如此。 例如,在CLISP中:
(defun f(x) (+ x 10))
(compile 'f)
(f 5)
==> 15
(disassemble #'f)
Disassembly of function F
(CONST 0) = 10
1 required argument
0 optional arguments
No rest parameter
No keyword parameters
4 byte-code instructions:
0 (CONST&PUSH 0) ; 10
1 (LOAD&PUSH 2)
2 (CALLSR 2 55) ; +
5 (SKIP&RET 2)
很简单吧?
现在,如果您使用 CLISP 的内部功能修改其常量向量并将 10
替换为其他内容,您将更改函数的行为:
(setf (sys::closure-const #'f 0) 42)
(f 7)
==> 49
这类似于在调试器下运行 C 程序并修改局部变量。
另请参阅Why does an elisp local variable keep its value in this case?和 Why does this function return a different value every time?
PS。请注意,这样做可能会导致严重崩溃(段错误)。当心。关于lambda - Lisp 代码数据对偶性、Lambda 表达式是常量吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64717429/