Common-Lisp:绑定形式参数,到底传递了啥?
Posted
技术标签:
【中文标题】Common-Lisp:绑定形式参数,到底传递了啥?【英文标题】:Common-Lisp: binding formal parameters, exactly what is passed?Common-Lisp:绑定形式参数,到底传递了什么? 【发布时间】:2016-09-10 12:17:33 【问题描述】:假设我们有一个符号,有一个符号值、一个函数值和一个属性列表,我们称之为q
。还假设我们有一个函数f
,其形式参数为v
,例如(f (v) ... )
并调用类似(f q)
的函数。
我的问题是:究竟传递给v
的是什么?是
q
的值;
q
的函数值;
q
的属性列表,
传递给形参v
?
如果它们都传递给v
,那么我对我们确实需要funcall
和apply
这两个函数感到困惑。如果v
真的有值和函数值,那么它肯定可以自己决定当我们写(v 3)
时,它必须使用v
的函数值而不是(funcall v 3)
。而当我们使用(setq v 3)
时,它必须使用v
的值。
究竟传递给v
的内容以及为什么v
不是一个符号,而只是一个“参数”或“变量”,对我来说是个谜。但我相信它在 Lisp 1.5 中确实是一个象征。但在普通的 Lisp 中,似乎有一些
混乱的余地。
【问题讨论】:
【参考方案1】:变量q
的值被传递。
(f q)
是一个求值形式,在这种情况下,名称q
被解释为一个变量。
如果要在函数f
中访问名称q
的函数值或属性列表,则需要引用名称并说'q
。通过这样做,您指的是函数值和属性列表值的全局注册表,而不是在函数f
中传递的本地信息。
只有变量q
的值在函数f
内部传递。
【讨论】:
我觉得这些信息很有帮助。它有时在文学作品中非常令人困惑。我在文献中看到了关于这一切的非常不同的观点和解释。有时我想知道这是否不是由 lisp 的悠久历史造成的。符号与变量的混淆、将函数传递给函数、有关绑定的术语是长期存在混淆的根源。【参考方案2】:如果你有
(f q)
意思是用q
的值调用函数f
。
-
Lisp 看到
f
是一个函数,所以整个(f q)
是一个函数形式。
Lisp 计算 q
的值。
Lisp 用一个值调用 f
。
Lisp 将局部变量 v
绑定到传递的值
Lisp 执行函数体f
...
v
在源代码中是一个符号,但它表示一个变量。在编译的代码中,符号消失了。由于 Common Lisp 使用词法绑定,变量现在是词法引用。
【讨论】:
【参考方案3】:既然你引用它,你传递符号q
不是它的任何值;可以使用(symbol-value v)
或(symbol-function v)
在f
中访问这些值。
您需要funcall
的原因是因为Common Lisp 使用符号的函数值当它出现在列表的头部时进行评估。所以如果你写
(v 3)
它将调用符号v
的函数值。但是传递给f
的值是v
的值,而不是函数值。但是当你写
(funcall v 3)
v
在参数列表中,因此对其进行评估以获取其值。该值是符号q
,当你尝试调用一个符号时,funcall
会查找它的函数值,所以在这种情况下它相当于
(funcall (symbol-function v) 3)
【讨论】:
以上是关于Common-Lisp:绑定形式参数,到底传递了啥?的主要内容,如果未能解决你的问题,请参考以下文章
View.post @Runnable 到底发生了啥 [重复]