和 之间有什么区别?和#'在 Lisp 中?

发布于 2024-10-15 21:49:13 字数 293 浏览 5 评论 0原文

两者看起来

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

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

工作原理都是一样的。

我还知道 ' 表示(引号符号),#' 表示(函数函数名称)。

但根本的区别是什么?为什么这两个在之前的mapcar中都可以工作?

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

爱本泡沫多脆弱 2024-10-22 21:49:13
'foo

计算结果为符号 FOO。

#'foo

计算结果为绑定到名称 FOO 的函数。

在 Lisp 中,当符号 FOO 具有函数绑定时,可以将符号作为函数调用。这里 CAR 是一个具有函数绑定的符号。

但这不起作用:

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

这是因为 FOO 作为符号无法访问本地词法函数,并且当 foo 不是其他地方定义的函数时,Lisp 系统会抱怨。

我们需要这样写:

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

这里的 (function foo) 或其简写符号 #'foo 指的是词法局部函数 FOO。

另请注意,在

(funcall #'foo ...)

vs

(funcall 'foo ...)

中,后者可能会多做一次间接寻址,因为它需要从符号中查找函数,而 #'foo 直接表示函数。

总结

如果符号具有函数绑定,则可以通过符号调用函数。

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

拍不死你 2024-10-22 21:49:13

为什么这两个都可以在以前的mapcar中使用?

mapcar 的文档说:

如果函数是一个符号,则它会被强制转换为函数,就像 符号功能

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.

牛↙奶布丁 2024-10-22 21:49:13

尝试将匿名函数 (lambda) 传递给您的 mapcar,您会发现 #' 是必需的,因为引用本身需要一个绑定到函数的符号,但该符号不存在于未命名的函数中:

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)

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)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文