Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's the difference between ' and #' in Lisp?

Tags:

lisp

quote

It seems both

(mapcar 'car '((foo bar) (foo1 bar1))) 

and

(mapcar #'car '((foo bar) (foo1 bar1)))

work as the same.

And I also know ' means (quote symbol) and #' means (function function-name).

But what's the underlying difference? Why these 2 both work in previous mapcar?

like image 697
Thomson Avatar asked Feb 05 '11 10:02

Thomson


3 Answers

'foo

evaluates to the symbol FOO.

#'foo

evaluates to the function bound to the name FOO.

In Lisp a symbol can be called as a function when the symbol FOO has a function binding. Here CAR is a symbol that has a function binding.

But this does not work:

(flet ((foo (a) (+ a 42)))
  (mapcar 'foo '(1 2 3 4 5)))

That's because FOO as a symbol does not access the local lexical function and the Lisp system will complain when foo is not a function defined elsewhere.

We need to write:

(flet ((foo (a) (+ a 42)))
  (mapcar #'foo '(1 2 3 4 5)))

Here the (function foo) or its shorthand notation #'foo refers to the lexical local function FOO.

Note also that in

(funcall #'foo ...)

vs.

(funcall 'foo ...)

The later might do one more indirection, since it needs to lookup the function from the symbol, while #'foo denotes the function directly.

Summary:

If a symbol has a function binding, calling a function through the symbol works.

like image 64
Rainer Joswig Avatar answered Nov 14 '22 04:11

Rainer Joswig


Why these 2 both work in previous mapcar?

The documentation for mapcar says:

If function is a symbol, it is coerced to a function as if by symbol-function.

like image 30
Ken Avatar answered Nov 14 '22 04:11

Ken


Try passing an anonymous function (lambda) to your mapcar and you'll see that #' is required since the quote by itself expects a symbol that is bound to a function, but the symbol doesn't exist in an un-named function:

CL-USER> (mapcar '(lambda (x) (format t "it is ~d" x)) (list 3 5 7))
; Evaluation aborted on #<TYPE-ERROR expected-type: (OR FUNCTION SYMBOL)
             datum: (LAMBDA (X) (FORMAT T "it is ~d" X))>.

vs:

CL-USER> (mapcar #'(lambda (x) (format t "it is ~d" x)) (list 3 5 7))
it is 3it is 5it is 7
(NIL NIL NIL)
like image 3
johnbakers Avatar answered Nov 14 '22 05:11

johnbakers