When should Emacs #'function syntax be used?
Asked Answered
C

3

44

Basically, when should I use Emacs Lisp's function procedure? I haven't found any examples in which there's a difference in behavior if you pass functions as arguments 'like-this or #'like-this. In fact, if I evaluate (eq 'goto-char #'goto-char) it returns t.

The Emacs Lisp code that I've come across rarely uses function/#'; the authors just quote/' everything.
Example: (add-hook 'emacs-lisp-hook 'turn-on-eldoc-mode)

However, I can find a few counterexamples. Here's one from the source code of Emacs 24.3's electric.el:

(add-hook 'post-self-insert-hook
          #'electric-indent-post-self-insert-function
          'append)

Guesses and further questions:

  • Is it just a Lisp-2 stylistic convention?
  • Does it have to do with byte-compilation?
  • Does it only matter for library writers? Like, if you intend for your code to be run under a huge number of environments and Emacs versions? (The corollary would be if you're just "dotfile-tinkering" then you don't need to worry about all this.)
  • When should I quote lambda-expressions? When can I leave them unquoted?
    E.g., (do-something '(lambda …
    versus (do-something (lambda …
  • Was there some limitation in an earlier version of Emacs that gave rise to these facets of elisp? Like, can I mostly ignore the difference between ' and #' as long as I'm using a version of Emacs more recent than X?
Croner answered 28/5, 2013 at 20:58 Comment(2)
see also #18391086Groat
Readers may find the "Linked" Q&As in the sidebar to be useful reading as well.Deirdredeism
Y
41

function (aka #') is used to quote functions, whereas quote (aka ') is used to quote data. Now, in Emacs-Lisp a symbol whose function cell is a function is itself a function, so #'symbol is just the same as 'symbol in practice (tho the intention is different, the first making it clear that one is not just talking about the symbol "symbol" but about the function named "symbol").

The place where the difference is not just stylistic is when quoting lambdas: '(lambda ...) is an expression which evaluates to a list whose first element is the symbol lambda. You're allowed to apply things like car and cdr to it, but you should not call it as if it were a function (although in practice it tends to work just fine). On the contrary #'(lambda ...) (which can be written just (lambda ...)) is an expression which evaluates to a function. That means you can't apply car to it, but the byte-compiler can look inside #'(lambda ...), perform macro-expansion in it, warn you if what it finds doesn't look kosher, etc...; For lexical-binding it even has to look inside in order to find the free variables to which that function refers.

Yoong answered 28/5, 2013 at 22:9 Comment(0)
D
13

In elisp #' is (in effect) purely about byte-compilation (edit: and since Emacs 24, also lexical closures); but you'll also probably never need to use it.

#'... is short-hand for (function ...) which is simply a variant of '... / (quote ...) that also hints to the byte-compiler that it can compile the quoted form as a function.

However, in modern Emacs (IIRC this was not always the case), (lambda ...) is equivalent to #'(lambda ...), so I believe you would rarely (if ever) need to write #'.

You would also rarely ever want to use '(lambda ...), for the reasons that Stefan has elaborated on (but 'symbol is fine).

This is covered in the manual under C-hig (elisp) Anonymous Functions RET (although there appears to be an error in the last piece of example code, as it is identical to the previous example (in Emacs 24.3.1)).

(n.b. Stefan's answer is definitive, but I'll keep this one here as it hopefully complements it.)

Deirdredeism answered 28/5, 2013 at 22:9 Comment(0)
U
8

In addition to the differences when quoting (lambda ...) forms there has recently (as of Emacs 24.4) been a change to bytecomp.el such that a warning is generated when a #'symbol form is used, but the function is not known to get defined at the end of the compilation.

Writing all function symbols with the function-quoting #'symbol syntax rather than the 'symbol syntax is thus somewhat preferable, since it allows the byte-compiler to check if you have used function names that are actually defined.

Previously (Emacs 24.3 and earlier), while the byte-compiler would warn when you call a function as (no-such-function ...) and it is not defined or cleanly imported from another file, something like (mapcar #'no-such-function ...) would have produced only a runtime-error without a compile-time warning.

The change means that both of these scenarios now produce compile-time warnings; however if you use (mapcar 'no-such-function ...) without using function-quoting then, once again, no compile-time warning can be generated. So the #' can help find errors (probably typos) early.

Function-quoting also helps with a top-down programming style, since the byte-compiler will then list the functions you have not yet implemented (but will miss functions specified with a normal quote).

Undeniable answered 24/9, 2013 at 13:18 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.