Subject: bug#77725: 31.0.50; Add support for types accepted by `cl-typep' to cl-generic?

From: Stefan Monnier <[email-masked]>
Date: Sun, 13 Apr 2025 13:10:38 -0400

> Thank you again for your very valuable input.
> I am afraid, this discussion just confirms that I don't understand well
> enough how cl-generic works, and how it can be improved the correct way :-(

In case it can help, here's some example:

    (cl-defmethod my-foo ((x symbol))
      (message "%S is a symbol" x))

If I call `(my-foo nil)` it will report that nil is a symbol, even
though `(cl-type-of nil)` returns `null` rather than `symbol`.

If I add a new method for `null`:

    (cl-defmethod my-foo ((x null))
      (message "%S is null" x)
      (cl-call-next-method))

Now a call to `(my-foo nil)` will report both that nil is null and that
it's a symbol (in that order).

For your `button` example, we'd similarly want that

    (cl-defmethod my-foo ((x icon))
      (message "%S is an icon" x)
      (cl-call-next-method))

`(my-foo 'button)` reports button as both an icon and a symbol (in that
order).  Now let's say we add:

    (defgtype face nil ()
      "Builtin face type."
      '(and symbol (satisfies facep)))

    (cl-defmethod my-foo ((x face))
      (message "%S is an face" x)
      (cl-call-next-method))

We'd want `(my-foo 'button)` now to report that button is an icon,
a face, and a symbol (and here I think it's OK if the ordering between
icon and face is arbitrary, tho they should both come before symbol).

One way you could do that is for your `(gtype-of 'button)` to return
some new `face&icon` type and to have your SPECIALIZERS-FUNCTION return
the list `(face icon symbol)` or `(icon face symbol)` for that type.

Does that help?

        Stefan