GNU bug report logs -
#77725
31.0.50; Add support for types accepted by `cl-typep' to cl-generic?
Previous Next
Full log
Message #35 received at 77725 <at> debbugs.gnu.org (full text, mbox):
> I understand more how cl-generic works, and I reworked gtype.el
> (attached) according to your inputs and my better understanding.
Looks good, thanks.
Some comments below.
> (eval-when-compile (require 'cl-macs)) ;For cl--find-class.
You can also use `cl-find-class` which doesn't require this gymnastics.
> (define-inline gtype-p (object)
> "Return non-nil if the type of OBJECT is a gtype."
> (inline-letevals (object)
> (inline-quote
> (and (symbolp ,object)
> (eq (type-of (cl--find-class ,object)) 'gtype-class)))))
I hope this function is not speed-critical (and so can be a plain `defun`).
> (define-inline gtype-parents (name)
> "Get parents of type with NAME.
> NAME is a symbol representing a type.
> Return a possibly empty list of types."
> (inline-quote
> (cl--class-allparents (cl--find-class ,name))))
Same here.
> (defun gtype--topologic-sort (graph &optional tie-breaker)
How is this different from `merge-ordered-lists`?
> ;;;###autoload
> (defmacro defgtype (name &optional parents &rest args)
> "Define NAME as a gtype that inherits from PARENTS.
Inheritance != subtyping. Better stick to the term "subtype" here since
there doesn't seem to be any inheritance going on here.
> If a gtype with NAME already exists, replace it.
>
> NAME is an unquoted symbol representing a gtype.
>
> Optional argument PARENTS is either an unquoted symbol or list of
> symbols other than NAME representing types parents of NAME.
> PARENTS nil or omitted means that NAME is a root type.
>
> Also pass NAME and ARGS to `cl-deftype' to define NAME as a new data
> type."
I get the impression that the role/impact of PARENTS is not explained
clearly enough. The explanation should be clear enough that the reader
can infer more or less what could happen if a parent is missing or if
a non-parent is incorrectly listed as a parent.
> (declare (debug cl-defmacro) (doc-string 4) (indent 3))
> (cl-with-gensyms (err)
> `(condition-case ,err
> (progn
> (cl-deftype ,name ,@args)
> (gtype--register ',name ',parents ',args))
> (error
> (gtype--unregister ',name)
> (error (error-message-string ,err))))))
Could we merge this into `cl-deftype`?
> (defmacro remgtype (name)
Try and stay within the namespace prefix.
> (defun gtype-of (object)
> "Return the most specific possible gtype OBJECT belongs to.
> Return an unique list of types OBJECT belongs to, ordered from the
> most specific type to the most general."
> ;; Ignore recursive call on the same OBJECT, which can legitimately
> ;; occur when, for example, a parent type is investigating whether
> ;; an object's type is that of one of its children.
> (unless (eq object gtype--object)
> (let ((gtype--object object)
> (found (list (cl-type-of object))))
> ;; Collect all gtypes OBJECT belongs to.
> (dolist (gtype gtype--list)
> (if (cl-typep object gtype)
> (push gtype found)))
> ;; Return an unique value of type.
> (with-memoization (gethash found gtype--unique)
> found))))
Since `gtype-of` is the function used to get the "tagcode" used for
method-dispatch, it is speed-critical.
But the above looks rather costly. 🙁
I think we could reduce this problem significantly with reasonably
simple changes to `cl-generic`: we could provide to the TAGCODE-FUNCTION
the list of specializers used by methods of the current
generic-function, so we'd only need to check those types which are
actually useful for the current dispatch.
[ Hmm... well, maybe not completely "simple" since it might have
some problematic impact on the `cl--generic-prefill-dispatchers`
mechanism, but that should be solvable. ]
> (defun gtype--specializers (tag &rest _)
> "If TAG is a gtype, return its specializers."
> (and (consp tag) (gtype-p (car tag))
> (with-memoization (gethash tag gtype--specializers)
> (merge-ordered-lists (mapcar #'gtype-parents tag)))))
AFAIK this function is only ever called with "tagcodes" returned by your
own TAGCODE-FUNCTION, so I think the `gtype-p` test is redundant.
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.