From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.ciao.gmane.io!not-for-mail From: Stefan Monnier Newsgroups: gmane.emacs.help Subject: Re: Colorize objects by method dispatch type Date: Fri, 03 Apr 2020 12:01:59 -0400 Message-ID: References: <87zhbv6jiu.fsf@web.de> <87r1x65z5v.fsf@web.de> <87zhbtjvsz.fsf@web.de> Mime-Version: 1.0 Content-Type: text/plain Injection-Info: ciao.gmane.io; posting-host="ciao.gmane.io:159.69.161.202"; logging-data="91314"; mail-complaints-to="usenet@ciao.gmane.io" User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/28.0.50 (gnu/linux) To: help-gnu-emacs@gnu.org Cancel-Lock: sha1:l5kHySU5m1y0WzmNOWj1z4FwAfk= Original-X-From: help-gnu-emacs-bounces+geh-help-gnu-emacs=m.gmane-mx.org@gnu.org Fri Apr 03 18:05:59 2020 Return-path: Envelope-to: geh-help-gnu-emacs@m.gmane-mx.org Original-Received: from lists.gnu.org ([209.51.188.17]) by ciao.gmane.io with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1jKOpT-000NeP-9v for geh-help-gnu-emacs@m.gmane-mx.org; Fri, 03 Apr 2020 18:05:59 +0200 Original-Received: from localhost ([::1]:57836 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1jKOpS-0001n7-B5 for geh-help-gnu-emacs@m.gmane-mx.org; Fri, 03 Apr 2020 12:05:58 -0400 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]:60356) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1jKOlr-0006yi-Sv for help-gnu-emacs@gnu.org; Fri, 03 Apr 2020 12:02:19 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1jKOlq-0000YC-EM for help-gnu-emacs@gnu.org; Fri, 03 Apr 2020 12:02:15 -0400 Original-Received: from ciao.gmane.io ([159.69.161.202]:41992) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1jKOlm-0000S6-Dd for help-gnu-emacs@gnu.org; Fri, 03 Apr 2020 12:02:14 -0400 Original-Received: from list by ciao.gmane.io with local (Exim 4.92) (envelope-from ) id 1jKOlj-000Isk-Dl for help-gnu-emacs@gnu.org; Fri, 03 Apr 2020 18:02:07 +0200 X-Injected-Via-Gmane: http://gmane.org/ X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 159.69.161.202 X-BeenThere: help-gnu-emacs@gnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Users list for the GNU Emacs text editor List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: help-gnu-emacs-bounces+geh-help-gnu-emacs=m.gmane-mx.org@gnu.org Original-Sender: "help-gnu-emacs" Xref: news.gmane.io gmane.emacs.help:122743 Archived-At: >> Also it's not clear to me exactly which part of `type-of` you don't like. > > `type-of' should be ok in most cases, but I'm looking for an alternative > for cases where e.g. `type-of' just says `cons' whereby the objects are > actually very different things that are identified with a tag as first > element or so. It's just that these are not represented with "official" > classes defined with defstruct. If the code in question doesn't use > methods but just a `cond' to distinguish I'm lost anyway but if it uses > methods than I could use the signature of the chosen method (for a > specified generic name) for hashing, or the signature of the most > specific method implementation. Then the color would only change if the > hierarchy of implementations changes, and in that case a changed color > would be acceptable. Hmm... so I guess ideally, you'd like to get the list of *specializers* that match your object when you call a particular generic function. You could write code to do that, but you'd have to dig into the innards of cl-generic.el: while cl-generic.el does need to compute something like that in order to perform the dispatch, the current code is not designed to give you just that information (it's only used as part of the code that does the method dispatch and the construction of the combined method). Here's how it works: - each specializer has (set of) matching generalizer. You can get that with `cl-generic-generalizers`. - The generalizer has code to take an arbitrary value and extra some "tag" from it. This `tag` is what is used in the usual dispatch (so computation of the tag is expected to be fast and the tag is then looked up in a hash-table). In a typical case, the tag is the `type-of` the object. You can get this code with `cl--generic-generalizer-tagcode-function`. - The generalizer also has code to take such a tag and return the set of specializers that match it. You can get this code with `cl--generic-generalizer-specializers-function`. So you'd need to take get all the methods of the generic function you're interested it, then for each one extract the specializer of the argument you're interested in (usually the first argument). That gives you the list of specializers which corresponds to the list of possible "classes" into which you want to divide your values. Then you use `cl-generic-generalizers` to turn those specializers into generalizers, then use `cl--generic-generalizer-tagcode-function` and `cl--generic-generalizer-specializers-function` to get the code that returns the set of specializers that match your value. For completeness, you can then intersect that set with your original set of specializers, in case you want to avoid the risk that `cl--generic-generalizer-specializers-function` returns "too fine-grained specializers". E.g. without this intersection you risk falling into a situation where every value gets a different set of specializers (because every value V matches its own specializer `(eql V)`). Then again, maybe (defun my-type-hash (v) (let ((type (if (and (consp v) (symbolp (car v))) (car v) (type-of v)))) (sxhash-equal (symbol-name type)))) is not such a bad idea after all ;-) Stefan