Subject: Re: bug#67008: 30.0.50; Multiple major mode parents

From: Stefan Monnier <[email-masked]>
Date: Sat, 11 Nov 2023 11:20:45 -0500

>>     * lisp/subr.el (merge-ordered-lists): New function. 
> That's nice to have, indeed.
> The implementation is a bit imperative (and quadratic?) but I assume it was
> tuned for performance (on small inputs).

I basically took the code from EIEIO, just massaged a bit to offer
a simpler API.  I'm sure there are ways to make it more efficient for
larger inputs, but I haven't put much thought into optimizing/tuning it.

>> +  "Merge LISTS in a consistent order.
>> +LISTS is a list of lists of elements.
>> +Merge them into a single list containing the same elements (removing
>> +duplicates) and obeying their relative positions in each list.
> I think the doc string should mention C3,

Fair enough.

> and that we use `eq` as equivalence predicate here.

Oops, indeed, thanks.

>> +If a consistent order does not exist, call ERROR-FUNCTION with
>> +the remaining lists.
>> +It should return the candidate to use to continue the merge
>> +By default we choose the first element of the first list."
>
> It's not obvious from the text what the arguments to such an error-function
> would look like and what the return value should be. None of the existing
> three callers seem to use this argument, for that matter.

Oh, that's a bug in my patch: the EIEIO code should use (to signal the
same error it currently signals).

> Given that `eieio--c3-merge-lists` raises an error if there is no total
> order, shouldn't the new code do so?

Yup.

> And we definitely should have tests (I completely understand that you didn't
> bothered writing any for something that may or may not actually be used).

I don't understand, there are many `if` tests in the code already.

> (Really wish we could hive off the whole CEDET tree to ELPA one day.)

Including EIEIO?
`defclass` is quite popular among contributors coming from the Common
Lisp world, so we have several packages in Emacs itself which use it:

    % grep -l '^(defclass' lisp/**/*.el | grep -v 'cedet\|eieio'
    lisp/auth-source.el
    lisp/emacs-lisp/chart.el
    lisp/emacs-lisp/vtable.el
    lisp/gnus/gnus-icalendar.el
    lisp/gnus/gnus-search.el
    lisp/international/emoji.el
    lisp/jsonrpc.el
    lisp/progmodes/eglot.el
    lisp/registry.el
    lisp/transient.el
    %

The use in `emoji.el` seems to be due to the use in `transient.el`.

        Stefan