Why evals (keymapp 'kmacro-keymap) to t,
and (keymapp 'kmacro-step-edit-map) to nil?
Both look like ordinary keymaps to me.
Function (predicate) keymapp tests the value of its argument to see if it is a keymap. In both cases, the sexps you provide pass a symbol as the argument, not a keymap.
However, as a special case keymapp also accepts a symbol whose function definition is a keymap. That is the case for kmacro-keymap but not for kmacro-step-edit-map. You can check this by applying function symbol-function to each of those symbols.
What you probably want to do is not pass an argument that evaluates to a symbol, but pass a symbol whose variable value is a keymap:
(keymapp kmacro-keymap)
(keymapp kmacro-step-edit-map)
Those both return t, as the value of each of those variables is a keymap.
Why the special case for an argument that is not, itself, a keymap but is instead a symbol whose function definition is a keymap? This is more or less a convenience. When would you want/need to define a symbol's function definition as a keymap? To be able to bind that function as a prefix key.
See the Elisp manual, node Prefix Keys. There you see this:
A “prefix key” is a key sequence whose binding is a keymap.
That means that the function that is bound to the key is itself a keymap. A symbol is made to be such a keymap-valued function by setting its function definition (its symbol-function) to the keymap. You can do this using function define-prefix-command.
(symbol-function 'kmacro-keymap)and(symbol-value 'kmacro-keymap)both eval to the same keymap? Isn't that wasted memory? – jue Apr 08 '19 at 07:41