多值散列通用 lisp

multiple-value hash common lisp

如何散列成对或三元组的“可等式对象,如符号或整数”?

在 python 中,我可以使用元组作为字典键,有没有办法在 lisp 中做到这一点而无需诉诸“相等测试”?

虽然某些实现可能会提供自定义哈希 table 函数的规定,但该标准仅定义了四个:

18.1.1 Hash-Table Operations

There are four kinds of hash tables: those whose keys are compared with eq, those whose keys are compared with eql, those whose keys are compared with equal, and those whose keys are compared with equalp.

这意味着如果您想使用标准散列 tables,那么您可能需要使用等于或 equalp 散列 table。我注意到你写道:

How can I hash pairs or triples of 'eq-able objects like symbols or ints?

虽然符号可以与 eq 进行可靠比较,但您不应将数字与 eq 进行比较。 eq 的文档说:

numbers with the same value need not be eq, … An implementation is permitted to make "copies" of characters and numbers at any time. The effect is that Common Lisp makes no guarantee that eq is true even when both its arguments are "the same thing" if that thing is a character or number.

并给出这个例子:

(eq 3 3)
;   =>  true
; OR=>  false

但是,如果您使用(小)整数元组,则可以轻松地对它们的函数进行哈希处理。例如,元组 (a,b,c) 可以映射到 2a×3b×5c。由于这样的函数会生成 eql 相当的唯一数字,因此您可以使用 eql哈希 table.

这种映射函数(也适用于符号)的另一种选择是使用 sxhash。这是一个标准的散列函数,应该为 equal 值生成相同的值。它是如何工作的,以及它到底做了什么,根本没有具体说明,但它的优点是它在同一实现的 Lisp 图像中是 stable(例如,运行 今天的 SBCL 的一个版本和明天,sxhash 将 return 与 equal 对象相同的结果)。当然,equal-hash-table 可能已经在为您执行此操作,因此您的里程数可能会有所不同。