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

From: David Ponce <[email-masked]>
Date: Wed, 30 Apr 2025 11:28:58 +0200

On 2025-04-29 20:02, Stefan Monnier wrote:
> Further comments:
> 
> - For a declaration like
> 
>      (cl-deftype list-of (elem-type)
>        `(and list
>              (satisfies ,(lambda (list)
>                            (cl-every (lambda (elem) (cl-typep elem elem-type))
>                                      list)))))
>      
>    we add the type to `cl--type-list` even though it's unusable there
>    (the `cl-typep` call in `cl-types-of` will always signal an error
>    because the type can't be used without argument).
> 
> - Regarding incorporation into CL-Lib: apparently we don't need to
>    `cl-deftype` in preloaded files, so `cl--type-deftype`
>    does not have to be in `cl-preloaded`.
>    But if `cl-deftype` expands to a call to it, then it needs to be
>    (auto)loaded even when CL-Lib is not loaded, which suggests putting it
>    into `cl-lib.el`.
>    Another option would be to make `cl-deftype` expand to code which does
>    not immediately call `cl--type-deftype`.  One way to do that would be to
>    wrap the call into a `(with-eval-after-load 'cl-lib ...)` or
>    something similar.
> 
> - One way to solve the problem with `list-of` (and even open up the
>    possibility to dispatch on complex types like `(list-of FOO)`) is to
>    populate `cl--type-dispatch-list` (i.e. the list of types that need to
>    be checked during dispatch) from `cl-generic-generalizers` so it
>    includes only those types for which there's a method, rather than all
>    defined types.
> 
> - The dispatch of types defined by `cl-deftype` is inherently unreliable
>    because the priority to use is not always the same.  For a type
>    defined as `(or integer symbol)` the priority should be *lower* than
>    the priority of the "typeof" generalizer, whereas for a type defined
>    as `(list-of (eql 'a))` the priority should be higher than that of the
>    "head" generalizer.
>    I don't think we can solve this problem, but it should be clearly
>    documented somewhere as a limitation.

I'm afraid this is all a bit beyond my grasp :-(
I'll defer to your expert opinion.

> 
> See below my current local changes (not really related to the comments
> above) as a diff w.r.t. the `scratch/cl-types` branch.

Thanks!

Attached you will find another version of cl-types.el, and
cl-types-test.el updated according to last changes.

I've included your edits in cl-types.el and improved `cl-types-of',
exploring the idea of ​​mapping a set of cl-types to a built-in type.  I
propose a simple solution derived from this idea, based on a "type
flag" (a symbol property for now) whose value lets us know whether the
type is worth checking, i.e. not in error, or match the built-in type
of the checked object.  Maybe, this "type property" could also become
a slot in the `cl-type-class' structure?

I also removed the test `(cl-type-class-p (cl--find-class type))'
which is always true, because in `cl--type-deftype' we only push such
types in `cl--type-list', and this list is only updated here and in
`cl--type-undefine' to remove a type.

David