2

I'm using mapcar in Common Lisp, and I've seen examples that use #' and ' in front of the + but they both appear to do the same thing. Does it matter which is used?

CL-USER> (mapcar '+ '(1 2) '(2 3))
(3 5)
CL-USER> (mapcar #'+ '(1 2) '(2 3))
(3 5)
jcheat
  • 121
  • 6
  • 1
    Please see [this question](http://stackoverflow.com/questions/23977617/use-of-a-k-a-read-macro). – Mark Karpov Jul 27 '14 at 05:23
  • 2
    The question marked as a duplicate includes a bunch of discussion about read macros (which is good, but is bit more than what's necessary here). The short answer is that the documentation for [mapcar](http://www.lispworks.com/documentation/HyperSpec/Body/f_mapc_.htm) says it takes a [function designator](http://www.lispworks.com/documentation/HyperSpec/Body/26_glo_f.htm#function_designator) which the glossary says is "a symbol (denoting the function named by that symbol in the global environment), or a function (denoting itself)." `'+` gives the symbol, and `#'+` gives the function. – Joshua Taylor Jul 27 '14 at 12:46

1 Answers1

2

They are often interchangeable, but are not the same thing. mapcar takes a function designator – a symbol designating a symbol-function or a function designating itself – which will be coerced to a function object. #'foo is a reader macro that expands to (function foo), which returns a function object by looking up the functional value of foo in the lexical environment, i.e. the innermost flet, labels, or the global function definition. Thus, nothing needs to be done to coerce it. If you use a quoted symbol with mapcar, however, it is coerced to a function using symbol-function, which will not work with non-global function definitions, as there are no fboundp symbols involved in this case. For example:

CL-USER> (flet ((frob (x) (1+ x)))
           (mapcar #'frob '(1 2 3)))
(2 3 4)
CL-USER> (flet ((frob (x) (1+ x)))
           (mapcar 'frob '(1 2 3)))
; Evaluation aborted on #<CCL::UNDEFINED-FUNCTION-CALL #x18AB7F1E>.

Also, when exactly the coercion happens, is implementation dependent, which has consequences for self or mutualy redefining code.

In general, using #' seems to be widely preferred nowadays, probably because it is felt to be more consistent – using #' everywhere you want to pass a function is a simple rule. I rarely see quoted symbols used with functions taking function designators in CL. In other dialects however, especially older or dynamically scoped ones like Emacs Lisp, passing quoted symbols to these functions is quite common.

danlei
  • 14,121
  • 5
  • 58
  • 82
  • 2
    Saying that mapcar takes something that will be coerced to a function might be misleading—you can coerce the a list that begins with `lambda`, e.g., `(list 'lambda '(x) 'x)` to a function, but it's not a function designator. A function designator is only a function (which designates itself) or a symbol (which designates its `symbol-function`). It's not likely a huge point of confusion, but `coerce` can do more than retrieve a designated function from a function designator. – Joshua Taylor Jul 28 '14 at 00:41
  • @JoshuaTaylor (Deleted a former comment by mistake.) Thanks for the comment! I wanted to keep things simple, and didn't want to define designators via coercion, but explain what happens when `mapcar` is called this way, as in the linked HS section. You're right about `coerce`, but I didn't want to describe this function either, which is why I didn't put the word coerce in monospace. Anyway, I edited the answer to avoid any ambiguities. – danlei Jul 28 '14 at 16:46