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

大兔子大兔子 提交于 2020-11-26 08:07:30

问题


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?


回答1:


'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.




回答2:


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.




回答3:


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)


来源:https://stackoverflow.com/questions/4906255/whats-the-difference-between-and-in-lisp

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!