Subject: Re: bug#78834: Feature request: make keymapp dereference symbol value slot

From: Stefan Monnier <[email-masked]>
Date: Thu, 19 Jun 2025 18:39:05 -0400

> I realized that and was doing something similar, admittedly less
> effeciently because I didn't know I can trust that all keymaps have the
> value slot set.

Your mental model is a bit off.  Keymaps don't have a "value slot".
IOW, your old loop was looking for "symbols that are keymaps" (which is
only those whose function slot contains a keymap), but your new function
looks for "variables which *contain* a keymap".

Most useful/important keymaps are stored in variables, so yes that loop
will find almost all of the keymaps.  Not all, because some keymaps are
produced dynamically or are stored only elsewhere (such as inside one
of the sublists of `minor-mode-map-alist`).

>> It's mostly used in very old code that uses the weird
>> `define-prefix-command` function, such as the code that sets up some of
>> the "core" keymaps like `ctl-x-5-prefix` `ESC-prefix` `ctl-x-4-prefix`,
>> `Control-X-prefix`.
> I was actually wondering why this was done, if it is just an
> optimization or if there is some other reason?  I am just curious, I
> don't really understand the idea behind.

You'd have to ask Richard.  IIUC one of the benefit is that you can
refer (by name) to a keymap before it's defined.  E.g. you can do

    (global-set-key [?\C-z] 'my-z-keymap)

and then have `my-z-keymap` autoloaded from some library the first time
you hit `C-z`.  I can't remember the last time I've seen this used
successfully (I tried to use it a few times, but the keymap always
ended up being "accidentally" autoloaded much too eagerly).

Maybe it was done simply because Richard thought of keymaps as kinds of
commands?

> It would be interesting to learn, if somebody knows and is willing to
> explain, since it is atypical to store value data in function slot.

Indeed.

>> It would break existing uses when the symbol has both
>> a `symbol-function` value and a `symbol-value` value.  We could
>> consider
> I saw the other functions using get_keymap, so I wasn't sure if they
> would complain or not. I have run Emacs today, the entire day, with that
> patch, I haven't noticed anything weird.

I wouldn't expect otherwise.  The affected cases would be corner cases.

> DEFUN ("keymapp", Fkeymapp, Skeymapp, 1, 1, 0,
>   (Lisp_Object object)
> {
>   if (NILP (object))
>     return Qnil;
>   if (CONSP (object) && EQ (XCAR (object), Qkeymap))
>     return object;
>
>   if (SYMBOLP (object))
>     {
>       Lisp_Object tem = indirect_function (object);
>       if (CONSP (tem) && EQ (XCAR (tem), Qkeymap))
>       return tem;
>
>       tem = find_symbol_value (object);
>       if (CONSP (tem) && EQ (XCAR (tem), Qkeymap))
>       return tem;
>     }
>
>   return Qnil;
> }

That would be wrong.  Code can expect that if `keymapp` returns non-nil,
then you do have a keymap and you can use functions like
`set-keymap-parent`, `lookup-key`, `map-keymap`, ... on it.  So if you
change `keymapp` to return non-nil for some symbols, you need to adjust
the other operations as well.

        Stefan