why defun is not the same as (setq

2019-04-03 08:06发布

I'm confused about how defun macro works, because

(defun x () "hello")

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

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)

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?

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.: I'm using SBCL.

2条回答
小情绪 Triste *
2楼-- · 2019-04-03 08:44

Common Lisp has multiple slots for each symbol, including a value-slot, and a function-slot. When you use the syntax (x), common lisp looks for the function-slot-binding of x. If you want to call the value-binding, use funcall or apply.

See http://cl-cookbook.sourceforge.net/functions.html

查看更多
Melony?
3楼-- · 2019-04-03 08:51

Common Lisp has different namespaces for functions and values.

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

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

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

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

or shorter:

#'foo    ->   #<the function foo>

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

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

In the case of DEFUN:

It is not (setf (symbol-value 'FOO) (lambda ...)).

It is more like (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))

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.

查看更多
登录 后发表回答