gpt4 book ai didi

function - 功能指示符的相等性

转载 作者:行者123 更新时间:2023-12-04 17:24:50 25 4
gpt4 key购买 nike

具有相同符号指示符的两个 Common Lisp 函数对象是否总是 eq?例如,这个比较似乎有效:

(defun foo (fn)
(let ((ht (make-hash-table)))
(eq (symbol-function (hash-table-test ht)) fn)))

FOO
* (foo #'eql)
T
*(foo #'equal)
NIL

但这可能依赖于不制作函数的潜在副本的实现,大概是出于效率的原因。由于 hash-table-test 返回一个符号指示符,另一个(可能更好的)eq 替代方案是从函数对象派生符号?一种方法比另一种更好吗?

最佳答案

Are two Common Lisp function objects with the same symbol designator always eq?

在 Common Lisp 中,函数是一段代码,无论是否编译。来自Glossary :

function n. 1. an object representing code, which can be called with zero or more arguments, and which produces zero or more values. 2. an object of type function.

另一方面,功能指示符可以是一个符号:

function designator n. a designator for a function; that is, an object that denotes a function and that is one of: a symbol (denoting the function named by that symbol in the global environment), or a function (denoting itself).

因此,作为函数指示符的符号是在特定上下文中或使用特定语法(如 #'symbol(函数符号), 产生一个函数,两个函数指示符的比较是它们所表示的函数的比较:

CL-USER> (eql #'car #'cdr)
NIL

CL-USER> (eql #'car (symbol-function 'car))
T

但请注意,此相等性测试只是功能对象(代码片段)的身份比较,如:

CL-USER> (eq #'car #'car)
T
CL-USER> (let ((a (lambda (x) (1+ x))))
(eq a a))
T

但不是代表它们的实际字节(代码!):

CL-USER> (let ((a (lambda (x) (car x)))
(eq a #'car))
NIL
CL-USER> (defun f (x) (1+ x))
F
CL-USER> (defun g (x) (1+ x))
G
CL-USER> (equalp (function f) (function g))
NIL
CL-USER> (equalp (lambda (x) (1+ x)) (lambda (x) (1+ x)))
NIL

请注意,在所有这些情况下,比较的两个函数不仅具有相同的“含义”,而且在大多数情况下具有相同的“源代码”,以相同的方式编译,并且在相同的输入数据上表现相同.这是因为函数在数学上是(可能)无限对(输入、输出)的集合,并且无法比较无限对象。

But this may rely on implementations not making latent copies of functions, presumably for reasons of efficiency.

用户无法复制一个函数(系统也没有任何理由执行一段代码的复制!),所以任何函数都等于它自己,就像任何指针只相等一样对自己。

Since hash-table-test returns a symbol designator, the other (possibly better) eq alternative would be to derive the symbol from the function object? Is one approach better than the other?

(我想你想要的是函数指示符,而不是符号指示符)

实际上,hash-table-test 通常仅将函数指示符作为符号返回,如 manual 中所述:

test---a function designator. For the four standardized hash table test functions (see make-hash-table), the test value returned is always a symbol. If an implementation permits additional tests, it is implementation-dependent whether such tests are returned as function objects or function names.

所以:

CL-USER> (type-of (hash-table-test (make-hash-table)))
SYMBOL
CL-USER> (eq 'eql (hash-table-test (make-hash-table)))
T
CL-USER> (eq #'eql (hash-table-test (make-hash-table)))
NIL

请注意,在最后一种情况下,我们将一个函数(#'eql 的值)与一个符号(hash-table-test 返回的值)进行比较显然,这种比较会返回错误值。

总结:

  1. 比较函数不是很合理,除非您想知道两个函数是否实际上是内存中的同一个对象(例如,如果这两个函数是相同的编译代码)。

  2. 将函数与其作为符号(函数名称)或列表的名称区分开来始终很重要,例如 (LAMBDA 参数主体),并决定我们要实际比较的内容。

关于function - 功能指示符的相等性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56673351/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com