【发布时间】:2021-04-09 08:56:10
【问题描述】:
我正在浏览一本 lisp 书,我正在查看 mapcar,我的问题是为什么这是有效的:
> (mapcar #'+ '(1 2) '(3 4))
但这个不是:
(mapcar + '(1 2) '(3 4))
换句话说,是否有理由在 lisp 中决定 mapcar 的第一个参数不能是函数本身,而必须是它的名称?这有什么用?
【问题讨论】:
标签: lisp common-lisp lisp-2
我正在浏览一本 lisp 书,我正在查看 mapcar,我的问题是为什么这是有效的:
> (mapcar #'+ '(1 2) '(3 4))
但这个不是:
(mapcar + '(1 2) '(3 4))
换句话说,是否有理由在 lisp 中决定 mapcar 的第一个参数不能是函数本身,而必须是它的名称?这有什么用?
【问题讨论】:
标签: lisp common-lisp lisp-2
是否有理由在 lisp 中决定 mapcar 的第一个参数不能是函数本身,而必须是它的名称?这有什么用?
只是在像 Common Lisp 这样的东西中,标识符+ 有多种不同的用途。它是一个变量、一个函数,以及其他各种东西。
写+ 表示变量。 read eval print 循环使用它。 + 的值是最后评估的表单,++ 的值是+ 的前一个值,+++ 的值是++ 的前一个值。
要告诉 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 检索符号 + 的全局函数值。
第四,我们也可以让函数对象成为源代码的一部分。
【讨论】:
mapcar,让 lisp 知道第一个参数的类型需要是什么并在其适当的命名空间中查找该对象自动地。您是否知道将这个责任交给调用者的权衡?
mapcar 是一个函数(不是宏,也不是特殊形式)。
#'+ 是一个函数。 Common Lisp 是所谓的“lisp 2”,这意味着它有两个命名空间:在评估复合形式期间,例如 (+ a b),函数位置在函数命名空间中查找,而其他位置在值命名空间。这意味着,例如,(append list list) 不会创建两个元素是 list 函数的列表:它会创建一个列表,其两个元素是 list 碰巧绑定的值。
但有时您需要在值位置获取名称的函数值:例如在mapcar 的第一个参数中。为此,有一个特殊的运算符,function:(mapcar (function +) x y) 将两个列表的元素相加。和quote 一样,function 也有一个读宏,即#'。
(为了让这更有趣,mapcar 实际上需要一个函数 designator 以便您可以使用函数的 nsme:(mapcar '+ x y) 会起作用,尽管它有点可怕。)
【讨论】:
func [arg [arg..]] 评估。