Why use #' before function arguments in emacs-lisp?
Asked Answered
H

1

18

I'm familiar with Emacs Lisp, but not Common (or any other) Lisp. Some Lisp programmers suggest (e.g. A basic function for emacs) that it's good to use #' in front of function arguments in Lisp code. For example:

(mapc #'my-fun '(1 2 3))

In Emacs Lisp, I believe that this is equivalent to

(mapc 'my-fun '(1 2 3))

From the elisp manual, section 12.7.

The read syntax #' is a short-hand for using function. The following forms are all equivalent:

 (lambda (x) (* x x))
 (function (lambda (x) (* x x)))
 #'(lambda (x) (* x x))

and the help for function

function is a special form in eval.c.

(function ARG)

Like quote, but preferred for objects which are functions. In byte compilation, function causes its argument to be compiled. quote cannot do that.

So it seems like a potential optimization, but no more. Moreover, coming from an ML/Haskell background, it seems strange to treat a function differently from any other data.

Question:

Do you agree that #' should be used in emacs-lisp function arguments? (A brief explanation of why they're needed in Common Lisp would be great as well.)

Notes:

I thought it may read a different cell when the #' is omitted (value vs function). But this seems wrong because the documentation for function doesn't say anything about grabbing the function cell. This is achieved by using symbol-function.

Related questions are

but they seem to suggest that the #' is unnecessary, at least in lambdas.

Hygrograph answered 22/8, 2013 at 20:52 Comment(3)
possible duplicate of When should Emacs #'function syntax be used?Headachy
EL and CL are both LISP2's. I.e. they have different namespaces for functions and variable. Not all LISPs are, eg. Scheme only has one and therefor doesn't need funcall at all. eg. (let ((x (lambda (y) (+ y y)))) (x 5))Semivitreous
Thank you for all the edits.Hygrograph
S
20

The quote character in #'foo has nothing to do with the one in 'foo.

#'foo is replaced at read time by (function foo). When that is compiled and executed, it looks up the functional definition named by foo (by defun, flet, labels or similar).

'foo is replaced at read time by (quote foo). When that is compiled and executed, it is simply replaced by the symbol foo.

Funcall and apply (and thus generally higher order functions) take function designators as arguments. A function designator can be a function or a symbol naming a function, so both #'foo and 'foo are function designators.

Therefore, the forms 'foo and #'foo seem interchangable at first glance. However, the lookup of the real function is done at different times—#'foo is looked up where it is invoked, while the function named by 'foo would only be looked up when it is finally applied.

If you use a function designator many times over, it is much more efficient to do the lookup just once, or even just at compile time. That can be a really big timesaver, and translates to a smoother user experience in an editor.

Stonge answered 22/8, 2013 at 21:25 Comment(2)
Specifically in Emacs Lisp, I do actually think 'foo and #'foo are equivalent, but using the latter is still a signal that you are after a function definition.Truthvalue
Do you want to use #'function for built in functions in bindings like (global-set-key (kbd "C-c s") 'save-buffer)? Or when calling an fset macro definition in a binding?Ageless

© 2022 - 2024 — McMap. All rights reserved.