I noticed some code in use-package-core.el where format is used to get a keyword's name as a string,

(format "%s" keyword)

Is there a reason this is preferable to using symbol-name?

(symbol-name keyword)

I would've expected symbol-name to be better in terms of readability and performance.


If KEYWORD is indeed always a symbol (in particular a keyword symbol) then IMO there's no special reason to use format. But there's no special reason not to, either: "better readability" is opinion-based, and performance difference is probably negligible.

But if it's not sure to be a symbol then using format with "%s" ensures that the resulting value is a string and not raise an error.

  • Good point. I'm not sure whether it's good or bad that this will produce a string rather than an error if KEYWORD is something other than a symbol, but it's an aspect I hadn't considered. – ivan Apr 18 at 16:08

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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.