On 2025-05-06 17:55, Stefan Monnier wrote: >> Debugger entered--Lisp error: (void-function kmacro-register-p) >> kmacro-register-p(2) >> cl-typep(2 (satisfies kmacro-register-p)) >> cl-typep(2 kmacro-register) >> cl-types-of(2) >> (seq-intersection (cl-types-of 2) types) >> [...] > > That's an incorrect `cl-deftype` call. AFAIK this was in `register.el` > but I actually removed it from there with: > > commit b1407b41a16c4a3ec15c88be91ba0ae1e65c212e > Author: Stefan Monnier > Date: Tue Apr 29 16:04:54 2025 -0400 > > register.el: Remove bogus deftypes and fix associated methods > > * lisp/register.el (frame-register, kmacro-register): Remove bogus deftypes. > (register--type) : Fix kmacro method and generalize it to > any OClosure. > (register--type) : Fix method and move it to ... > * lisp/frameset.el (register--type) : ... here, > where `frameset-register` is defined. > > I guess I need to rebase the `cl-types` branch. 🙂 I also see a similar error with type `frame-register': "cl-types-of frame-register: Symbol’s function definition is void: frameset-register-p" > >>>> (cl-types-of 'button) => button match `icon' type, so the `cl--type-flag' >>>> of `icon' is set to `symbol' (cl-type-of or root-type of `button') >>>> >>>> (cl-types-of 12) => `root-type' of 12 is `fixnum', so cl-types-of doesn't >>>> waste time checking if 12 if of type `icon', because we are sure it cannot >>>> match (their root-types are different). An so on with other types whose >>>> root-type is known. >>> That makes a lot of sense, indeed. >>> But ... does it work for: >>> (cl-deftype my-pair () >>> `(and number (satisfies ,(lambda (x) (zerop (logand x 1)))))) >>> (cl-types-of (expt 2 128)) => (expt 2 128) matches `my-pair` type, so >>> the `cl--type-flag` of `my-pair` is set to `bignum`. Now when I try >>> (cl-types-of 4) won't it skip `my-pair` because (cl-type-of 4) is not >>> `bignum`? What am I missing? >> >> Good point! The problem is that the type returned by `cl-type-of' is too >> specific. If I instead use `type-of' to map a set of cl-types to a >> built-in type, your example above works as expected, as do other >> categories I've tested, like symbol, cons, string, etc. >> Using `type-of' to determine a set of cl-types seems like a good >> compromise to me. WDYT? > > That just solves some occurrences, but not all: > > (cl-deftype my-pair-length () > `(and sequence (satisfies ,(lambda (x) (zerop (logand (length x) 1)))))) > > and now (cl-types-of [1 2]) will set `cl--type-flag` to > `vector` so (cl-types-of "ab") will miss `my-pair-length`! > > If you want more cases, think of > > (cl-deftype my-foo () > '(or TYPE1 TYPE2)) Of course, you are right ;-) I guess a general solution is much more complex than what I thought. And maybe risk to be more costly than the current implementation without set of cl-types. Please find attached a patch proposal for the branch. Mainly to ensure that types not suitable for cl-defmethod (erroneous type or type with arguments) will signal an "Unknown specializer" error when trying to use them as argument type in cl-defmethod. Also to improve handling of errors with recursive types that can lead to error in the error handler in `cl-types-of', because the maximum recursion limit is reached. 2025-05-06 David Ponce * lisp/emacs-lisp/cl-lib.el (cl-generic-generalizers :extra "cl-types-of"): Fix indentation. * lisp/emacs-lisp/cl-macs.el (cl-deftype): Don't register types that can't be used without arguments, so they are not valid types for method arguments. * lisp/emacs-lisp/cl-extra.el (cl--type-dispatch-list): Move definition before first use. (cl-types-of): Temporarily raise the recursion limit in error handler. Remove the type in error from valid specializers. * lisp/emacs-lisp/cl-preloaded.el (cl--type-deftype): Remove the ARGLIST argument, no more used. Don't exclude here types that can't be used without arguments. Thanks!