我正在阅读一本 lisp 书,我正在看mapcar
,我的问题是为什么这是有效的:
> (mapcar #'+ '(1 2) '(3 4))
但这不是:
(mapcar + '(1 2) '(3 4))
换句话说,是否有理由在 lisp 中决定第一个参数mapcar
不能是函数本身,而必须是它的名称?这有什么用?
我正在阅读一本 lisp 书,我正在看mapcar
,我的问题是为什么这是有效的:
> (mapcar #'+ '(1 2) '(3 4))
但这不是:
(mapcar + '(1 2) '(3 4))
换句话说,是否有理由在 lisp 中决定第一个参数mapcar
不能是函数本身,而必须是它的名称?这有什么用?
是否有理由在 lisp 中决定 mapcar 的第一个参数不能是函数本身,而必须是它的名称?这有什么用?
只是在 Common Lisp 之类的东西中,标识符+
有多种不同的用途。它是一个变量、一个函数以及其他各种东西。
写作+
意味着变量。它由read eval print loop使用。的值+
是最后评估的形式,的值++
是 的前一个值+
,而 的值+++
是 的前一个值++
。
要告诉 Common Lisp 您想使用标识符的函数值,+
必须写得(function +)
更短#'+
。
因此
(mapcar (function +) '(1 2) '(3 4))
或更短
(mapcar #'+ '(1 2) '(3 4))
实际上意味着使用函数 + 和列表 (1 2) 和 (3 4) 调用 mapcar
还有另外两种使用该功能的方法+
。
(mapcar '+ '(1 2) '(3 4))
上面将让 Lisp 检索符号的全局函数值+
。
第四,我们也可以让函数对象成为源代码的一部分。
#'+
是一个函数。Common Lisp 是所谓的“lisp 2”,这意味着它有两个命名空间:在评估复合形式时,例如(+ a b)
,函数位置在函数命名空间中查找,而其他位置在值命名空间中查找。这意味着,例如(append list list)
,不会创建一个两个元素是list
函数的列表:它会创建一个列表,其两个元素是list
碰巧绑定的值。
但有时您需要在值位置获取名称的函数值:一个示例在mapcar
. 为此,有一个特殊的运算符function
:(mapcar (function +) x y)
添加两个列表的元素。像quote
,function
有一个读取宏,即#'
.
(为了让这更有趣,mapcar
实际上需要一个函数指示符 ,这样你就可以使用函数的 nsme:(mapcar '+ x y)
将工作,虽然它有点可怕。)