Endless Parentheses

Concise ramblings on Emacs productivity.

Get in the habit of using sharp quote

The sharp quote (or function quote, or simply #') is an abbreviation for the function form. It is essentially a version of quote (or ') which enables byte-compilation, but its actual usefulness has changed throughout the years.

A little over two decades ago, it was used to quote lambda forms. You see, '(lambda (x) (* x x)) was just a raw list to the byte-compiler, but #'(lambda (x) (* x x)) was an actual function that could be compiled. Now-a-days—or rather, now-a-decades—the lambda form sharp-quotes itself, meaning a plain (lambda (x) (* x x)) is identical to the #' version. In fact, you should never quote your lambdas with either quotes.

On the other hand, just as you'd expect the sharp quote to become redundant for the elisp programmer, a new use arises for it. The compiler throws a warning whenever it notices you've used an undefined function, say (not-defined "oops"), but it can't do the same for something like (mapcar 'not-defined some-list) because it doesn't know that symbol is the name of a function. The sharp quote is a way of conveying that information to the compiler, so if it runs into (mapcar #'not-defined some-list), it can throw a warning accordingly.

So it is always good practice to sharp quote every symbol that is the name of a function, whether it's going into a mapcar, an apply, a funcall, or anything else. Adhering to this actually unearthed a small bug in one of my packages.

And of course, we can make things more convenient.

(defun endless/sharp ()
  "Insert #' unless in a string or comment."
  (call-interactively #'self-insert-command)
  (let ((ppss (syntax-ppss)))
    (unless (or (elt ppss 3)
                (elt ppss 4)
                (eq (char-after) ?'))
      (insert "'"))))

(define-key emacs-lisp-mode-map "#" #'endless/sharp)

Tags: style, keybind, lisp, init.el, emacs

Say thanks on Gratipay
comments powered by Disqus