Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

why defun is not the same as (setq <name> <lambda>)?

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.

like image 894
Filipp Avatar asked Jun 26 '12 17:06

Filipp


People also ask

What is SETQ in Lisp?

(setq var1 form1 var2 form2 ...) is the simple variable assignment statement of Lisp. First form1 is evaluated and the result is stored in the variable var1, then form2 is evaluated and the result stored in var2, and so forth. setq may be used for assignment of both lexical and dynamic variables.

What does t stand for in LISP?

LISP uses the self-evaluating symbol nil to mean false. Anything other than nil means true. Unless we have a reason not to, we usually use the self-evaluating symbol t to stand for true. LISP provides a standard set of logical functions, for example and, or, and not.


2 Answers

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.

like image 96
Rainer Joswig Avatar answered Sep 25 '22 06:09

Rainer Joswig


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

like image 31
Marcin Avatar answered Sep 23 '22 06:09

Marcin