How is sharp quote (#') different from symbol-

2019-08-12 02:32发布

问题:

To me these operators seem to do the same thing. Both take a symbol and return the function associated with it. Is there any difference?

elisp evaluation returns the following:

(defun foo (x) (+ 1 x))
foo
(foo 3)
4
#'foo

Which I don't understand either.

Furthermore is there a difference between common lisp and elisp? I'm learning from resources on either.

回答1:

Common Lisp:

SYMBOL-FUNCTION can't retrieve functions from lexically bound functions. FUNCTION references the lexically bound function by default. #'foo is just a shorter notation for (FUNCTION foo).

CL-USER 1 > (defun foo () 'foo)
FOO

CL-USER 2 > (flet ((foo () 'bar))
              (list (funcall (symbol-function 'foo))
                    (funcall #'foo)
                    (funcall (function foo))
                    (eq (function foo) (symbol-function 'foo))))
(FOO BAR BAR NIL)

CL-USER 3 > (eq (function foo) (symbol-function 'foo))
T


回答2:

Rainer's answer discusses the things that you can do with function that you can't do with symbol-function, namely retrieve the value of lexically scoped functions, but there are a few other differences too.

The special operator FUNCTION

The special operator FUNCTION provides a way to find the functional value of a name in a lexical environment. Its argument is either a function name or a lambda expression. That function can take a lambda expression means that you can write: (function (lambda (x) (list x x))). The term function name includes more than just symbols. It also includes lists of the form (setf name), which means that you can do things like (function (setf car)).

The accessor SYMBOL-FUNCTION

The accessor symbol-function, on the other hand, lets you retrieve and set the functional value of a symbol. Since it requires a symbol, you can't do (symbol-function (lambda …)) or (function (setf name)). Symbol-function also can't see lexical environments; it only works with global definitions. E.g.,

(flet ((foo () 'result))
  (symbol-function 'foo))
;=> NIL

Since symbol-function is an accessor, you can change the value of a function's symbol with it. E.g.:

CL-USER> (setf (symbol-function 'foo) (lambda () 42))
#<FUNCTION (LAMBDA ()) {1005D29AAB}>
CL-USER> (foo)
42
CL-USER> (setf (symbol-function 'foo) (lambda () 26))
#<FUNCTION (LAMBDA ()) {1005D75B9B}>
CL-USER> (foo)
26

The accessor FDEFINITION

There's also the accessor fdefinition which is kind of like symbol-function in that is can only access globally defined functions, but kind of like function in that it can access of symbols and (setf name) lists. However, it does not retrieve the value of lambda functions.