GNU bug report logs -
#77725
31.0.50; Add support for types accepted by `cl-typep' to cl-generic?
Previous Next
Full log
Message #122 received at 77725 <at> debbugs.gnu.org (full text, mbox):
> Exactly, I fully agree, the question is "how to keep track of the
> children"?
You could approximate it with `after-load-functions`. Or, with the
proposed patch, you could use an advice on `cl--type-deftype`. Once you
do that, you won't need to break circularity in `cl-types-of`.
> I wonder if it would be possible to do something when the type is
> (re)defined? For example, pass the type once defined to some kind of
> "after-defined-hook" that could adjust the environment accordingly.
Maybe more generally we could/should provide "fast" (i.e. cached)
versions of `cl--class-allparents` and `cl--class-children`.
[ And remove those `--`. ]
>>> This makes me think that errors that might occur when calling
>>> `cl-typep' should be handled in `cl-types-of' to prevent an
>>> incorrect definition from impacting method dispatching on types
>>> correctly defined.
>>> WDYT?
>> Maybe. I'd tend to think that `cl-typep` should never error, so if
>> it ever does (which would indicate a bug in some `cl-deftype`), we
>> wouldn't want to hide that error.
> Unfortunately, currently `cl-typep' can error, but currently the
> impact is limited to the broken definition. Here is an example of
> broken definition:
>
> (cl-deftype bad-type ()
> '(satisfies unknown-function))
But this is bug in the definition of the type.
> But, when any type defined by 'cl-deftype' can also be a method type
> argument, any broken type can also break dispatching of method for
> other types. So, such errors need to be caught and reported by
> `cl-types-of'. For now, I updated `cl-types-of' accordingly.
You could also take the position that we shouldn't catch those errors
and instead put pressure to fix those broken `cl-deftype` definitions.
> I am afraid, I still don't see how I can implement this "common
> approach" to break circularity.
I think it would look something like:
(defvar cl--type-pending nil)
(defun cl--typep (o type)
;; Like `cl-typep` but with recursion-check.
(let ((entry (cons o type)))
;; Note: `member` is not quite right.
(if (member entry cl--type-pending)
;; We're called recursively while in the process of testing
;; if `o` is of type `type`, so presume it's true for now,
;; rather than inf-loop.
t
(let ((cl--type-pending (cons cl--type-pending)))
(cl-typep o type)))))
(defun cl-types-of (o)
(let ((types ()))
(dolist (type ...alltypes...)
(when (cl--typep o type)
(push type types))))))
...types...))
> When I consider that a type "match" before to check, it will still
> match after a cycle is detected, if I understood correctly your
> explanation. So, a circular type will always match for any objet?
If the type is "trivially circular", yes. Otherwise, not necessarily.
E.g.
(cl-deftype is-cons (t1 t2)
`(and cons (satisfies
,(lambda (x)
(and (cl--typep (car x) t1) (cl--typep (car x) t2))))))
(cl-deftype list-of-int ()
`(is-cons integer (or null list-of-int)))
and then
(let ((x (list 1 2 3 4 5)))
(setcdr (last x) x)
(cl--typep x 'list-of-int))
would terminate and return t but
(let ((x (list "1" "2" "3" "4" "5")))
(setcdr (last x) x)
(cl--typep x 'list-of-int))
would return nil.
> Please find attached a new simpler and cleaner version of
> cl-types-test.el. All tests pass for me :-)
Looks good, thanks.
> Also attached my last version of cl-types.el. For now, I prefer to
> work on separate files. Based on your previous proposal, it should
> not be difficult to merge the code in existing libraries when/if we
> are satisfied of the implementation ;-)
It would be good to check that the split I proposed works correctly, tho.
The main issues are likely to be around whether things are autoloaded
when they to.
Stefan
This bug report was last modified 10 days ago.
Previous Next
GNU bug tracking system
Copyright (C) 1999 Darren O. Benham,
1997,2003 nCipher Corporation Ltd,
1994-97 Ian Jackson.