Is there a reason this is preferable to using symbol-name
?
No, I think it just comes down to style and context. E.g. I can imagine someone preferring to consistently use format
everywhere, because it can handle more than just symbols, and the format string can be easily changed.
See also Drew's answer.
I would've expected symbol-name
to be better in terms of readability
That's entirely subjective and context-dependent, I'm afraid.
and performance.
I'd expect the same. symbol-name
just checks that it has a symbol, untags it, and returns the stored name:
DEFUN ("symbol-name", Fsymbol_name, Ssymbol_name, 1, 1, 0,
doc: /* Return SYMBOL's name, a string. */)
(register Lisp_Object symbol)
{
register Lisp_Object name;
CHECK_SYMBOL (symbol);
name = SYMBOL_NAME (symbol);
return name;
}
Although format
essentially boils down to the same thing for symbols:
/* ... */
if (SYMBOLP (arg))
{
spec->argument = arg = SYMBOL_NAME (arg);
if (STRING_MULTIBYTE (arg) && ! multibyte)
{
multibyte = true;
goto retry;
}
}
/* ... */
there is a lot more bookkeeping involved, and potentially a string allocation, so it is quite likely to run slower.
Having said that, the time it takes to evaluate (format "%s" keyword)
should be so miniscule that for all practical purposes there is no performance difference between that and (symbol-name keyword)
.
As always, it is better to profile your code for performance, rather than trying to reason about minor (and probably premature) optimisations like this.
Another thing to consider when comparing seemingly identical definitions, is whether one or the other has a dedicated opcode (which tends to result in faster execution) or is marked as pure
or side-effect-free
.
KEYWORD
is something other than a symbol, but it's an aspect I hadn't considered. – ivan Apr 18 '21 at 16:08