在Common Lisp中,标准库中是否有一个函数只返回给定的参数(即不操作数据)?此功能相当于(lambda (x) x)
。我希望将它用作可选参数的默认值。例如,这样的函数将替换:{/ p>中的(lambda (x) x)
(defun some-function (value &optional (transformation (lambda (x) x)))
(other-function (funcall transformation value))
答案 0 :(得分:10)
看看identity
:
BTW,ANSI CL标准规定了近千个符号。 你不可能一夜之间学会它们。 此外,Lisp是一种具有丰富历史的语言,所以如果你想要一些东西"通用",很可能是语言提供的,或者某些(半)标准库。功能 IDENTITY
语法:
身份 对象⇒对象
参数和值:
对象 -an object。
说明
返回其参数 object 。
提问!不要重新发明自行车。
答案 1 :(得分:10)
sds's answer描述了身份功能,该功能符合您要求的规范:它几乎只是(lambda (x) x)
。但是,值得注意的是,在像
(defun some-function (value &optional (transformation (lambda (x) x)))
(other-function (funcall transformation value))
将转换描述为键 可能更为惯用,并让 nil 表明没有关键功能应该应用于该值。 许多 Common Lisp函数中存在此行为。例如,成员接受一个应用于序列的每个元素的键参数,以生成与要搜索的项目进行比较的值:
CL-USER> (member nil '(1 2 3 4 nil 5 6 7 8))
(NIL 5 6 7 8)
CL-USER> (member nil '(1 2 3 4 nil 5 6 7 8) :key 'oddp)
(2 3 4 NIL 5 6 7 8)
默认行为与将身份作为密钥传递相同:
CL-USER> (member nil '(1 2 3 4 nil 5 6 7 8))
(NIL 5 6 7 8)
CL-USER> (member nil '(1 2 3 4 nil 5 6 7 8) :key 'identity)
(NIL 5 6 7 8)
但是,默认值不是 标识,而是 nil 。 member的HyperSpec说明了关键:
key - 一个参数函数的指示符,或 nil 。
这在17.2.1 Satisfying a Two-Argument Test中指明,其中指出:
如果提供了:key参数,则它是函数的指示符 每个Ei作为一个参数被调用的一个参数,并产生一个 对象Zi用于比较。 (如果没有:关键参数,Zi 是Ei。)
如果你想采用这种类型的约定,那么你的代码就像
(defun some-function (value &optional transformation)
(other-function (if (null transformation) value (funcall transformation value))))
在你的情况下,这可能不是一个很大的区别,但它将避免额外的函数调用。一般来说,这可能会有所帮助,因为它可以更容易地将关键参数传递给库函数,而不必担心它们是否 nil 。
答案 2 :(得分:2)
为了扩展这个问题,#'identity
会在你有一个参数时返回它的参数。 #'list
会将多个参数作为列表返回,#'values
会将它们作为多个值返回,它们用于相同的目的但确实具有非常不同的API。