diff --git a/doc/lispref/hash.texi b/doc/lispref/hash.texi index 8389c21..4607bb0 100644 --- a/doc/lispref/hash.texi +++ b/doc/lispref/hash.texi @@ -268,18 +268,43 @@ under the property @code{hash-table-test}; the property value's form is @code{(@var{test-fn} @var{hash-fn})}. @end defun address@hidden sxhash obj address@hidden sxhash-equal obj This function returns a hash code for Lisp object @var{obj}. This is an integer which reflects the contents of @var{obj} and the other Lisp objects it points to. -If two objects @var{obj1} and @var{obj2} are equal, then @code{(sxhash address@hidden)} and @code{(sxhash @var{obj2})} are the same integer. +If two objects @var{obj1} and @var{obj2} are @code{equal}, then address@hidden(sxhash-equal @var{obj1})} and @code{(sxhash-equal @var{obj2})} +are the same integer. -If the two objects are not equal, the values returned by @code{sxhash} -are usually different, but not always; once in a rare while, by luck, -you will encounter two distinct-looking objects that give the same -result from @code{sxhash}. +If the two objects are not @code{equal}, the values returned by address@hidden are usually different, but not always; once in a +rare while, by luck, you will encounter two distinct-looking objects +that give the same result from @code{sxhash-equal}. + address@hidden Lisp note:} In Common Lisp a similar function is called address@hidden Emacs provides this name as a compatibility alias for address@hidden address@hidden defun + address@hidden sxhash-eq obj +This function returns a hash code for Lisp object @var{obj}. Its +result reflects identity of @var{obj}, but not its contents. + +If two objects @var{obj1} and @var{obj2} are @code{eq}, then address@hidden(xhash @var{obj1})} and @code{(xhash @var{obj2})} are the same +integer. address@hidden defun + address@hidden sxhash-eql obj +This function returns a hash code for Lisp object @var{obj} suitable +for @code{eql} comparison. I.e. it reflects identity of @var{obj} +except for the case where the object is a float number, in which case +hash code is generated for the value. + +If two objects @var{obj1} and @var{obj2} are @code{eql}, then address@hidden(xhash @var{obj1})} and @code{(xhash @var{obj2})} are the same +integer. @end defun This example creates a hash table whose keys are strings that are @@ -289,7 +314,7 @@ compared case-insensitively. (defun case-fold-string= (a b) (eq t (compare-strings a nil nil b nil nil t))) (defun case-fold-string-hash (a) - (sxhash (upcase a))) + (sxhash-equal (upcase a))) (define-hash-table-test 'case-fold 'case-fold-string= 'case-fold-string-hash) @@ -302,7 +327,7 @@ predefined test value @code{equal}. The keys can be any Lisp object, and equal-looking objects are considered the same key. @example -(define-hash-table-test 'contents-hash 'equal 'sxhash) +(define-hash-table-test 'contents-hash 'equal 'sxhash-equal) (make-hash-table :test 'contents-hash) @end example diff --git a/etc/NEWS b/etc/NEWS index d38bc3d..6ec82f8 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -217,6 +217,17 @@ outermost parenthesis. ** The function 'redirect-debugging-output' now works on platforms other than GNU/Linux. ++++ +** New functions 'sxhash-eq' and 'sxhash-eql' return hash codes of a +Lisp object suitable for use with 'eq' and 'eql' correspondingly. If +two objects are 'eq' ('eql'), then the result of 'sxhash-eq' +('sxhash-eql') on them will be the same. + ++++ +** Function 'sxhash' has been renamed to 'sxhash-equal' for +consistency with the new functions. For compatibility, 'sxhash' +remains as an alias to 'sxhash-equal'. + * Changes in Emacs 25.2 on Non-Free Operating Systems diff --git a/lisp/emacs-lisp/byte-opt.el b/lisp/emacs-lisp/byte-opt.el index b3bf4a5..dbaf2bc 100644 --- a/lisp/emacs-lisp/byte-opt.el +++ b/lisp/emacs-lisp/byte-opt.el @@ -1209,8 +1209,9 @@ radians-to-degrees rassq rassoc read-from-string regexp-quote region-beginning region-end reverse round sin sqrt string string< string= string-equal string-lessp string-to-char - string-to-int string-to-number substring sxhash symbol-function - symbol-name symbol-plist symbol-value string-make-unibyte + string-to-int string-to-number substring + sxhash sxhash-equal sxhash-eq sxhash-eql + symbol-function symbol-name symbol-plist symbol-value string-make-unibyte string-make-multibyte string-as-multibyte string-as-unibyte string-to-multibyte tan truncate diff --git a/lisp/subr.el b/lisp/subr.el index cad6319..a6d6fa4 100644 --- a/lisp/subr.el +++ b/lisp/subr.el @@ -66,6 +66,7 @@ For more information, see Info node `(elisp)Declaring Functions'." ;;;; Basic Lisp macros. (defalias 'not 'null) +(defalias 'sxhash 'sxhash-equal) (defmacro noreturn (form) "Evaluate FORM, expecting it not to return. diff --git a/src/fns.c b/src/fns.c index 1ace3bb..da74b9c 100644 --- a/src/fns.c +++ b/src/fns.c @@ -4447,8 +4447,26 @@ sxhash (Lisp_Object obj, int depth) Lisp Interface ***********************************************************************/ +DEFUN ("sxhash-eq", Fsxhash_eq, Ssxhash_eq, 1, 1, 0, + doc: /* Compute identity hash code for OBJ and return it as integer. +In other words, hash codes of two non-`eq' lists will be (most likely) +different, even if the lists contain the same elements. */) + (Lisp_Object obj) +{ + return make_number (hashfn_eq (NULL, obj)); +} + +DEFUN ("sxhash-eql", Fsxhash_eql, Ssxhash_eql, 1, 1, 0, + doc: /* Compute identity hash code for OBJ and return it as integer. +In comparison to `sxhash-eq', it is also guaranteed that hash codes +of equal float numbers will be the same, even if the numbers are not +the same Lisp object. */) + (Lisp_Object obj) +{ + return make_number (hashfn_eql (NULL, obj)); +} -DEFUN ("sxhash", Fsxhash, Ssxhash, 1, 1, 0, +DEFUN ("sxhash-equal", Fsxhash_equal, Ssxhash_equal, 1, 1, 0, doc: /* Compute a hash code for OBJ and return it as integer. */) (Lisp_Object obj) { @@ -5066,7 +5084,9 @@ syms_of_fns (void) DEFSYM (Qkey_or_value, "key-or-value"); DEFSYM (Qkey_and_value, "key-and-value"); - defsubr (&Ssxhash); + defsubr (&Ssxhash_eq); + defsubr (&Ssxhash_eql); + defsubr (&Ssxhash_equal); defsubr (&Smake_hash_table); defsubr (&Scopy_hash_table); defsubr (&Shash_table_count);