为什么defun与(setq< name>< lambda>)不同? [英] why defun is not the same as (setq <name> <lambda>)?

查看:121
本文介绍了为什么defun与(setq< name>< lambda>)不同?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对defun宏的工作方式感到困惑,因为

I'm confused about how defun macro works, because

(defun x () "hello")

将创建函数x,但符号x仍未绑定.

will create function x, but symbol x still will be unbound.

如果我将一些lambda绑定到x,则x将具有一个值,但解释器不会将其视为具有以下形式的函数:

If I'll bind some lambda to x then x will have a value, but it will not be treated by interpreter as function in form like this:

(x)

我认为这与defun应该在全局环境中定义功能这一事实有关,但是我不确定它的确切含义.为什么我不能在当前环境中遮盖它?

I think that it is related to the fact that defun should define function in global environment, but I'm not sure what does it exactly mean. Why can't I shadow it in the current environment?

如果绑定了一些lambda,是否有任何方法可以强制解释器将符号视为函数?例如:

Is there any way to force interpreter treat symbol as function if some lambda was bound to it? For example:

(setq y (lambda () "I want to be a named function"))
(y)

P.S .:我正在使用SBCL.

P.S.: I'm using SBCL.

推荐答案

Common Lisp具有用于函数和值的不同命名空间.

Common Lisp has different namespaces for functions and values.

您可以使用DEFUNFLETLABELS和其他一些名称在函数名称空间中定义函数.

You define functions in the function namespace with DEFUN, FLET, LABELS and some others.

如果要获取功能对象作为值,请使用FUNCTION.

If you want to get a function object as a value, you use FUNCTION.

(defun foo (x) (1+ x))

(function foo)   ->  #<the function foo>

或更短:

#'foo    ->   #<the function foo>

如果要调用函数,则编写(foo 100).

If you want to call a function, then you write (foo 100).

如果要将函数作为值调用,则需要使用FUNCALLAPPLY:

If you want to call the function as a value then you need to use FUNCALL or APPLY:

(funcall #'foo 1)

您可以传递函数并调用它们:

You can pass functions around and call them:

(defun bar (f arg)
  (funcall f arg arg))

(bar #'+ 2)  ->  4

对于DEFUN:

不是(setf (symbol-value 'FOO) (lambda ...)).

它更像是(setf (symbol-function 'foo) (lambda ...)).

请注意,这两个名称空间使您可以编写:

Note that the two namespaces enable you to write:

(defun foo (list)
  (list list))

(foo '(1 2 3))  ->  ((1 2 3))

内置函数LIST和变量LIST之间没有冲突.由于我们有两个不同的名称空间,因此我们可以将相同的名称用于两个不同的目的.

There is no conflict between the built-in function LIST and the variable LIST. Since we have two different namespaces we can use the same name for two different purposes.

还请注意,在使用局部函数的情况下,不涉及任何符号.命名空间不必与符号绑定.因此,对于局部变量,无法通过符号名称进行功能查找.

Note also that in the case of local functions there is no symbol involved. The namespaces are not necessarily tied to symbols. Thus for local variables a function lookup via a symbol name is not possible.

这篇关于为什么defun与(setq&lt; name&gt;&lt; lambda&gt;)不同?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆