unofficial mirror of help-gnu-emacs@gnu.org
 help / color / mirror / Atom feed
From: Stefan Monnier <monnier@iro.umontreal.ca>
To: help-gnu-emacs@gnu.org
Subject: Re: Colorize objects by method dispatch type
Date: Fri, 03 Apr 2020 12:01:59 -0400	[thread overview]
Message-ID: <jwvsghkk23y.fsf-monnier+emacs@gnu.org> (raw)
In-Reply-To: 87zhbtjvsz.fsf@web.de

>> 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




  reply	other threads:[~2020-04-03 16:01 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-04-01 20:25 Colorize objects by method dispatch type Michael Heerdegen
2020-04-01 21:46 ` Michael Heerdegen
2020-04-02  3:00 ` Stefan Monnier
2020-04-02  3:45   ` Michael Heerdegen
2020-04-02 12:56     ` Stefan Monnier
2020-04-02 23:46       ` Michael Heerdegen
2020-04-03 16:01         ` Stefan Monnier [this message]
2020-04-03 23:23           ` Michael Heerdegen

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.gnu.org/software/emacs/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=jwvsghkk23y.fsf-monnier+emacs@gnu.org \
    --to=monnier@iro.umontreal.ca \
    --cc=help-gnu-emacs@gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).