unofficial mirror of bug-gnu-emacs@gnu.org 
 help / color / mirror / code / Atom feed
* bug#71116: 30.0.50; comp-normalize-valset doesn't sort consistently
@ 2024-05-22 13:27 Daniel Clemente
  2024-05-22 19:10 ` Andrea Corallo
  0 siblings, 1 reply; 3+ messages in thread
From: Daniel Clemente @ 2024-05-22 13:27 UTC (permalink / raw)
  To: 71116; +Cc: acorallo

[-- Attachment #1: Type: text/plain, Size: 1779 bytes --]

Current code from comp-cstr.el:

(defun comp-normalize-valset (valset)
  "Sort and remove duplicates from VALSET then return it."
  (cl-sort (cl-remove-duplicates valset :test #'eq)
           (lambda (x y)
             (cond
              ((and (symbolp x) (symbolp y))
               (string< x y))
              ((and (symbolp x) (not (symbolp y)))
               t)
              ((and (not (symbolp x)) (symbolp y))
               nil)
              ((or (consp x) (consp y)
                   nil))
              (t
               (< (sxhash-equal x)
                  (sxhash-equal y)))))))


This part:
              ((or (consp x) (consp y)
                   nil))

Seems like a typo; as if this was intended:
              ((or (consp x) (consp y))
                   nil)


In practice, it means it's not sorting well. The presence of a cons can
even change how the other elements are sorted:

;; This produces: ((a . 1) 2 3)
(comp-normalize-valset '(
  2
  3
  (a . 1)
))

;; This produces: (2 3 (a . 1))
(comp-normalize-valset '(
  (a . 1)
  2
  3
))

;; This produces: (3 (a . 1) 2)
(comp-normalize-valset '(
  2
  (a . 1)
  3
))

Since all three examples use a list with the same elements, I would expect
the same result after sorting: a sorted list (by some definition of
sorted). Otherwise the function documentation must be adjusted.

I'm just reporting this because I was reading new code and found this part
hard to understand. I'm not familiar with the comp-cstr.el code or with how
this affects native compilation, or whether there's any bug. My example
doesn't represent how the actual code is used.

For context, the original intention was to avoid comparing conses with
sxhash-equal.
https://lists.gnu.org/archive/html/emacs-devel/2024-02/msg00406.html

[-- Attachment #2: Type: text/html, Size: 2260 bytes --]

^ permalink raw reply	[flat|nested] 3+ messages in thread

* bug#71116: 30.0.50; comp-normalize-valset doesn't sort consistently
  2024-05-22 13:27 bug#71116: 30.0.50; comp-normalize-valset doesn't sort consistently Daniel Clemente
@ 2024-05-22 19:10 ` Andrea Corallo
  2024-05-27 18:50   ` Andrea Corallo
  0 siblings, 1 reply; 3+ messages in thread
From: Andrea Corallo @ 2024-05-22 19:10 UTC (permalink / raw)
  To: Daniel Clemente; +Cc: 71116

Daniel Clemente <n142857@gmail.com> writes:

> Current code from comp-cstr.el:
>
> (defun comp-normalize-valset (valset)
>   "Sort and remove duplicates from VALSET then return it."
>   (cl-sort (cl-remove-duplicates valset :test #'eq)
>            (lambda (x y)
>              (cond
>               ((and (symbolp x) (symbolp y))
>                (string< x y))
>               ((and (symbolp x) (not (symbolp y)))
>                t)
>               ((and (not (symbolp x)) (symbolp y))
>                nil)
>               ((or (consp x) (consp y)
>                    nil))
>               (t
>                (< (sxhash-equal x)
>                   (sxhash-equal y)))))))
>
> This part:
>               ((or (consp x) (consp y)
>                    nil))
>
> Seems like a typo; as if this was intended:
>               ((or (consp x) (consp y))
>                    nil)
>
> In practice, it means it's not sorting well. The presence of a cons can even change how the other elements are sorted:
>
> ;; This produces: ((a . 1) 2 3)
> (comp-normalize-valset '(
>   2
>   3
>   (a . 1)
> ))
>
> ;; This produces: (2 3 (a . 1))
> (comp-normalize-valset '(
>   (a . 1)
>   2
>   3
> ))
>
> ;; This produces: (3 (a . 1) 2)
> (comp-normalize-valset '(
>   2
>   (a . 1)
>   3
> ))
>
> Since all three examples use a list with the same elements, I would expect the same result after sorting: a sorted list
> (by some definition of sorted). Otherwise the function documentation must be adjusted.
>
> I'm just reporting this because I was reading new code and found this part hard to understand. I'm not familiar with the
> comp-cstr.el code or with how this affects native compilation, or whether there's any bug. My example doesn't represent
> how the actual code is used.
>
> For context, the original intention was to avoid comparing conses with sxhash-equal.
> https://lists.gnu.org/archive/html/emacs-devel/2024-02/msg00406.html

Yes this is my todo list, I think for how the code is now sorting should
not even be necessary anymore, so I want to give it a try at remove it
entirely.

  Andrea





^ permalink raw reply	[flat|nested] 3+ messages in thread

* bug#71116: 30.0.50; comp-normalize-valset doesn't sort consistently
  2024-05-22 19:10 ` Andrea Corallo
@ 2024-05-27 18:50   ` Andrea Corallo
  0 siblings, 0 replies; 3+ messages in thread
From: Andrea Corallo @ 2024-05-27 18:50 UTC (permalink / raw)
  To: Daniel Clemente; +Cc: 71116-done

Andrea Corallo <acorallo@gnu.org> writes:

> Daniel Clemente <n142857@gmail.com> writes:
>
>> Current code from comp-cstr.el:
>>
>> (defun comp-normalize-valset (valset)
>>   "Sort and remove duplicates from VALSET then return it."
>>   (cl-sort (cl-remove-duplicates valset :test #'eq)
>>            (lambda (x y)
>>              (cond
>>               ((and (symbolp x) (symbolp y))
>>                (string< x y))
>>               ((and (symbolp x) (not (symbolp y)))
>>                t)
>>               ((and (not (symbolp x)) (symbolp y))
>>                nil)
>>               ((or (consp x) (consp y)
>>                    nil))
>>               (t
>>                (< (sxhash-equal x)
>>                   (sxhash-equal y)))))))
>>
>> This part:
>>               ((or (consp x) (consp y)
>>                    nil))
>>
>> Seems like a typo; as if this was intended:
>>               ((or (consp x) (consp y))
>>                    nil)
>>
>> In practice, it means it's not sorting well. The presence of a cons can even change how the other elements are sorted:
>>
>> ;; This produces: ((a . 1) 2 3)
>> (comp-normalize-valset '(
>>   2
>>   3
>>   (a . 1)
>> ))
>>
>> ;; This produces: (2 3 (a . 1))
>> (comp-normalize-valset '(
>>   (a . 1)
>>   2
>>   3
>> ))
>>
>> ;; This produces: (3 (a . 1) 2)
>> (comp-normalize-valset '(
>>   2
>>   (a . 1)
>>   3
>> ))
>>
>> Since all three examples use a list with the same elements, I would expect the same result after sorting: a sorted list
>> (by some definition of sorted). Otherwise the function documentation must be adjusted.
>>
>> I'm just reporting this because I was reading new code and found this part hard to understand. I'm not familiar with the
>> comp-cstr.el code or with how this affects native compilation, or whether there's any bug. My example doesn't represent
>> how the actual code is used.
>>
>> For context, the original intention was to avoid comparing conses with sxhash-equal.
>> https://lists.gnu.org/archive/html/emacs-devel/2024-02/msg00406.html
>
> Yes this is my todo list, I think for how the code is now sorting should
> not even be necessary anymore, so I want to give it a try at remove it
> entirely.

Right, after thinking about I believe keeping some sorting is beneficial
performance-wise to have good cache hit rate.  With 509e7f877ba
'comp-normalize-valset' sort by type and within each type it sorts only
(alphabetically) strings and symbols, so we don't rely anymore on
'sxhash-equal'.

Closing this then, happy to reopen if necessary.

Thanks!

  Andrea






^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2024-05-27 18:50 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-05-22 13:27 bug#71116: 30.0.50; comp-normalize-valset doesn't sort consistently Daniel Clemente
2024-05-22 19:10 ` Andrea Corallo
2024-05-27 18:50   ` Andrea Corallo

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).